`
liuzhaomin
  • 浏览: 204316 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

HashMap,基于数组来存储数据

阅读更多
HashMap采用数组方式存储key,value构成的Entry,无容量限制;
HashMap基于key hash寻找entry对象存放到数组的位置,对于hash冲突采用链表的方式来解决;
HashMap在插入元素时可能会要扩大数组的容量,在扩大容量时要重新计算hash,并复制对象到新的数组中;
HashMap是非线程安全的;

写道
Hash table based implementation of the Map interface. This implementation provides all of the optional map operations, and permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable , except that it is unsynchronized and permits nulls.) This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.

This implementation provides constant-time performance for the basic operations (get and put ), assuming the hash function disperses the elements properly among the buckets. Iteration over collection views requires time proportional to the "capacity" of the HashMap instance (the number of buckets) plus its size (the number of key-value mappings). Thus, it's very important not to set the initial capacity too high (or the load factor too low) if iteration performance is important.

An instance of HashMap has two parameters that affect its performance: initial capacity and load factor . The capacity is the number of buckets in the hash table, and the initial capacity is simply the capacity at the time the hash table is created. The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased. When the number of entries in the hash table exceeds the product of the load factor and the current capacity, the hash table is rehashed (that is, internal data structures are rebuilt) so that the hash table has approximately twice the number of buckets.

As a general rule, the default load factor (.75) offers a good tradeoff between time and space costs. Higher values decrease the space overhead but increase the lookup cost (reflected in most of the operations of the HashMap class, including get and put ). The expected number of entries in the map and its load factor should be taken into account when setting its initial capacity, so as to minimize the number of rehash operations. If the initial capacity is greater than the maximum number of entries divided by the load factor, no rehash operations will ever occur.

If many mappings are to be stored in a HashMap instance, creating it with a sufficiently large capacity will allow the mappings to be stored more efficiently than letting it perform automatic rehashing as needed to grow the table.

Note that this implementation is not synchronized. If multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with a key that an instance already contains is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the map. If no such object exists, the map should be "wrapped" using the Collections.synchronizedMap method. This is best done at creation time, to prevent accidental unsynchronized access to the map:

Map m = Collections.synchronizedMap(new HashMap(...));

The iterators returned by all of this class's "collection view methods" are fail-fast : if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a ConcurrentModificationException . Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.
 

 

public class HashMap<K,V>
    extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable
{

    /**
     * The default initial capacity - MUST be a power of two.
     */
    static final int DEFAULT_INITIAL_CAPACITY = 16;

    /**
     * The maximum capacity, used if a higher value is implicitly specified
     * by either of the constructors with arguments.
     * MUST be a power of two <= 1<<30.
     */
    static final int MAXIMUM_CAPACITY = 1 << 30;

    /**
     * The load factor used when none specified in constructor.
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    /**
     * The table, resized as necessary. Length MUST Always be a power of two.
     */
    transient Entry[] table;

    /**
     * The number of key-value mappings contained in this map.
     */
    transient int size;

    /**
     * The next size value at which to resize (capacity * load factor).
     * @serial
     */
    int threshold;

    /**
     * The load factor for the hash table.
     *
     * @serial
     */
    final float loadFactor;

    /**
     * The number of times this HashMap has been structurally modified
     * Structural modifications are those that change the number of mappings in
     * the HashMap or otherwise modify its internal structure (e.g.,
     * rehash).  This field is used to make iterators on Collection-views of
     * the HashMap fail-fast.  (See ConcurrentModificationException).
     */
    transient volatile int modCount;

    /**
     * Constructs an empty <tt>HashMap</tt> with the specified initial
     * capacity and load factor.
     *
     * @param  initialCapacity the initial capacity
     * @param  loadFactor      the load factor
     * @throws IllegalArgumentException if the initial capacity is negative
     *         or the load factor is nonpositive
     */
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);

        // Find a power of 2 >= initialCapacity
        int capacity = 1;
        while (capacity < initialCapacity)
            capacity <<= 1;

        this.loadFactor = loadFactor;
        threshold = (int)(capacity * loadFactor);
        table = new Entry[capacity];
        init();
    }

 

分享到:
评论

相关推荐

    Java基础-模拟HashMap集合(基于数组和链表) 数组和链表.pdf

    Java基础-模拟HashMap集合(基于数组和链表) 在本文中,我们将详细介绍如何模拟Java的HashMap集合,使用数组和链表来实现Hash表的存储。我们将从基本概念开始,逐步深入到HashMap的实现细节中。 什么是HashMap? ...

    学习笔记:三数组实现的HashMap

    - 在标准HashMap中,一个数组存储键,另一个数组存储值,而第三个数组(或称为“链表”或“桶”)存储指向键值对的引用。这种实现可能是为了优化空间效率和查找性能。 - 第一个数组存储键的哈希值,第二个数组存储...

    Java集合,HashMap底层实现和原理(1.7数组+链表与1.8+的数组+链表+红黑树) 数组和链表.pdf

    在JDK1.7中,HashMap的实现主要基于数组和链表。数组是HashMap的基础结构,链表是用于解决哈希冲突的问题。每个键值对组成了一个Entry实体,Entry类实际上是一个单向的链表结构,它具有Next指针,可以连接下一个...

    05.HashMap相关面试题

    HashMap 的实现机制基于数组+链表/红黑树。 * 使用数组来存储键值对,数组的索引是根据键的哈希码计算得到的。 * 使用链表或红黑树来解决 Hash 冲突问题。 7. HashMap 的查询时间复杂度 HashMap 的查询时间复杂度...

    Java数组+链表简单实现HashMap的put和get 数组和链表.pdf

    在标准的Java SDK中,HashMap的实现是基于哈希表的数据结构,它内部使用数组配合链表来解决哈希冲突。这里我们将分析一个简单的自定义HashMap实现,它使用Java数组和链表来完成put和get操作。 首先,我们看到类`...

    HashMap介绍和使用

    HashMap内部采用数组加链表(或红黑树)的形式存储数据,这种结构称为“链表散列”。数组作为主存储结构,而链表则用来处理哈希冲突(即多个键值对映射到数组同一位置的情况)。 **1.2 数据结构示例** ```java /**...

    HashMap的数据结构

    HashMap是Java编程语言中一个非常重要的数据结构,它属于集合框架的一部分,主要用于存储键值对(Key-Value)数据。HashMap在内部实现上基于哈希表,也称为散列表,它提供了一种快速查找、插入和删除数据的方法,...

    HashMap和HashTable底层原理以及常见面试题

    2. 性能:HashMap的性能比HashTable好,因为HashMap使用数组和链表来存储键值对,而HashTable使用链表来存储键值对。 3. null键:HashMap允许存放null键和null值,而HashTable不允许存放null键和null值。 常见面试...

    基于共享内存的hashmap

    标题中的“基于共享内存的HashMap”指的是在多进程或多线程环境中,使用共享内存作为存储机制的哈希映射数据结构。哈希映射(HashMap)是一种常用的数据结构,它通过键值对(key-value pairs)的方式快速存取数据,...

    hashmap面试题_hashmap_

    HashMap的内部实现基于数组+链表/红黑树的结构。数组中的每个元素都是一个Entry对象,每个Entry包含键值对和指向下一个Entry的引用。当冲突较多导致链表过长时,会自动转换为红黑树,以保证查找效率。 三、HashMap...

    基于HashMap的用户标签处理兼Java中HashMap实现原理研究.pdf

    在实现方法中,我们首先考虑的是直接更新数据表,读取CSV,通过mysql的“INSERT INTO table (key1) VALUES (val1) ON DUPLICATE KEY UPDATE c=c+1”语法来插入更新每基于HashMap的用户标签处理。然而,经过测试发现...

    HashMap底层原理.pdf

    HashMap的存储结构基于数组+链表+红黑树的方式实现。在JDK 1.8之前,HashMap仅使用数组和链表结构,但在JDK 1.8及之后的版本中,当链表长度超过阈值时,链表会转换成红黑树结构,以减少查找时间复杂度。这一改变主要...

    java中HashMap详解.pdf

    在Java中,当创建一个HashMap时,其底层使用数组来存储数据。键值对存储在Entry对象中,Entry对象包含了键、值以及下一个Entry对象的引用(链表的一部分,用于解决散列冲突)。 当put一个元素时,首先会计算键的...

    基于JavaScript的HashMap实现

    这篇博客“基于JavaScript的HashMap实现”可能详细阐述了如何通过自定义函数来创建一个高效且灵活的HashMap数据结构。 在JavaScript中,对象(Object)是哈希表的一种表现形式,其内部通过键(key)来定位值(value...

    简单的QQ聊天程序,用hashmap实现信息的存储

    在这个简单的QQ聊天程序中,开发者利用了HashMap这一数据结构来存储和管理信息,以实现高效的消息传递和用户交互。 HashMap在Java中是集合框架的一个重要组成部分,它是一种基于哈希表的Map接口实现。HashMap提供了...

    HashMap总结

    HashMap 是基于哈希表(Hash Table)实现的,哈希表是一个存储键值对的数据结构,它使用哈希函数将键转换为索引,然后将键值对存储在数组中。HashMap 使用链表来解决哈希冲突的问题,即当两个键的哈希值相同时,...

    简单的三维整型数组

    总结来说,这个“简单的三维整型数组”项目是利用ArrayList和二维数组构建的动态三维数据结构,旨在提供一种灵活且可扩展的方式来存储和操作整型数值。随着项目的不断发展,我们可以期待更多优化和增强,以满足各种...

    hashmap 实例

    ArrayList 内部基于数组实现,适合随机访问,但在中间或开头插入/删除元素时效率低,因为需要移动大量元素。LinkedList 采用链表结构,插入/删除速度快,但访问元素时需从头遍历,效率较低。根据具体需求,选择合适...

    Java中HashMap的工作机制

    在Java中,HashMap是一种广泛使用的数据结构,它基于哈希表的Map接口实现。哈希表是一种通过哈希过程将键映射到特定位置的数据结构,该位置存储了键对应的值。在详细探讨Java中HashMap的工作机制之前,首先需要理解...

    java HashMap原理分析

    Java HashMap是一种基于哈希表的数据结构,它的存储原理是通过将Key-Value对存储在一个数组中,每个数组元素是一个链表,链表中的每个元素是一个Entry对象,Entry对象包含了Key、Value和指向下一个Entry对象的引用。...

Global site tag (gtag.js) - Google Analytics