hashmap 是怎么扩容的
时间: 2024-01-15 22:33:39 浏览: 69
HashMap 在初始化时会创建一个指定容量大小的哈希表,当存储的键值对数量超过了负载因子(默认为 0.75)与当前容量的乘积时,就会触发扩容操作。
具体扩容过程如下:
1.创建一个新的哈希表,容量为原来的两倍。
2.遍历原哈希表中的每个 Entry 对象,将它们重新分配到新的哈希表中。
3.重新分配时,会根据每个 Entry 对象的 key 值重新计算哈希值,并将它们放到新的哈希表的对应位置上。如果新位置上已经有其他 Entry 对象,则将它们组织成一个链表。
4.最后,将原哈希表指向新的哈希表,完成扩容操作。
需要注意的是,扩容操作会比较耗时,因为需要将原哈希表中的所有 Entry 对象重新分配到新的哈希表中。因此,在创建 HashMap 时,尽量预估需要存储的键值对数量,并设置合适的初始容量,避免频繁扩容。
相关问题
hashmap自动扩容
ArrayList和HashMap都有扩容的机制。
ArrayList的扩容是在添加元素时,如果当前元素个数已经达到了底层数组的容量,就会创建一个新的数组,将原数组中的元素复制到新数组中,并将新元素添加到新数组中。新数组的容量一般是原数组容量的1.5倍。
HashMap的扩容是在添加元素时,如果当前元素个数已经达到了负载因子(默认为.75)乘以当前数组容量的大小,就会创建一个新的数组,将原数组中的元素重新计算哈希值后,放入新数组中。新数组的容量一般是原数组容量的两倍。
需要注意的是,扩容会涉及到数组的复制和元素的重新计算哈希值,所以会有一定的性能开销。因此,在预知数据量较大的情况下,可以通过设置初始容量来减少扩容的次数,提高性能。
HashMap具体扩容
HashMap的扩容是在put操作中进行的。当HashMap中元素数量达到了负载因子(默认为0.75)乘以当前容量时,就会触发扩容操作。具体步骤如下:
1. 创建一个新的数组,长度为原数组长度的两倍。
2. 将原数组中的每个元素重新计算其在新数组中的位置,并放入新数组中。
3. 如果新数组中的某个位置已经有元素了,那么就采用链表或红黑树等数据结构来存储冲突的元素。
4. 将原数组指向新数组,完成扩容。
需要注意的是,在扩容期间,如果有其他线程在进行put或者remove操作,可能会导致数据结构出现异常。为了避免这种情况,Java中的HashMap使用了一种叫做“链表尾插法”的技巧,即在扩容的过程中,新数组中的每个位置都会将原数组中的元素按照插入的顺序重新插入到链表的尾部,这样就可以保证原先的顺序不变,从而避免了线程安全问题。
阅读全文