学习来源:链接: link.
put方法的过程
什么时候扩容(resize)?
当向容器添加元素的时候,会判断当前容器的元素个数,如果大于等于阈值,即当前数组的长度乘以加载因子的值的时候,就要自动扩容。
当然Java里的数组是无法自动扩容的,方法是使用一个新的数组代替已有的容量小的数组。
JDK1.7 扩容举例(put操作是头插法)
hash(){
return key % table.length;
}
假设了我们的hash算法就是简单的用key mod 一下数组的大小。
其中的哈希桶数组table的size=2,put顺序为头插法:依次为 5、7、3。在mod 2以后都冲突在table[1]这里了。这里假设负载因子 loadFactor=1,即当键值对的实际大小size 大于 table的实际大小时进行扩容。接下来的三个步骤是哈希桶数组 resize成4,然后所有的Node重新rehash的过程。
JDK1.8 扩容举例(put操作是尾插法)
我们在扩充HashMap的时候,不需要像JDK1.7的实现那样重新计算hash,只需要看看原来的hash值新增的那个bit是1还是0就好了,是0的话索引没变,是1的话索引变成“原索引+oldCap”,可以看看下图为16扩充为32的resize示意图:
JDK1.7 resize过程中 多线程可能会导致链表死循环的情况
链接: link.