当哈希表里的entry(键值对)超过一定阈值时,哈希表会进行再哈希(rehash)。再哈希后的哈希表的桶的个数之前的两倍 。(threshold=capacity*factor)
验证
public class HashMapL {
public static void main(String[] args) {
HashMap<Integer, Integer> hashMap = new HashMap<>();
hashMap.put(null, null); //允许空空键值对
for(int i=0; i<16; i++){
hashMap.put(i, i); //自动装箱
}
}
下面来一步步的研究
HashMap<Integer, Integer> hashMap = new HashMap<>();
从上图可以看出
负载因子——0.75
table——null。尚未分配。了解拉链式哈希表的人就会轻易知道它是一个链表数组。
阈值——0。这个值是在给table分配空间后才会计算
hashMap.put(null, null);
从上图可以看到,现在table已经初始化了。
table——拥有一个元素 "null=null",并且从图片最下面可以看到,它是一个包含16个元素的数组
table的id——24
继续按下一步,直到size=threshold=12,此刻table的id和之前的一样,还是id=24
现在再按一次下一步,向HashMap里添加一个元素,让元素的总数size大于阈值threshold
变化
id 24-->104
大小 16-->32
阈值 12-->24
结论
- 当size>threshold时就会进行再哈希。
- 再哈希后,HashMap就会自动扩容为之前的2倍,并且用一个新的对象代替原来的对象。
由此也可得知,自动扩容是需要消耗资源的,要尽量减少自动扩容的发生。