以下内容基于jdk1.7,关于hashmap在jdk1.8中的内容参考
https://www.cnblogs.com/yanzige/p/8392142.html
在添加元素的时候,如果元素大于等于闸阀,同时即将发生碰撞,hashmap会进行扩容:
扩容的时候,会创建新的table来装旧table的元素。
方法如下:
voidtransfer(Entry[] newTable, boolean rehash) {int newCapacity =newTable.length;//for循环中的代码,逐个遍历链表,重新计算索引位置,将老数组数据复制到新数组中去(数组不存储实际数据,所以仅仅是拷贝引用而已)
for (Entrye : table) {while(null !=e) {
Entry next =e.next;if(rehash) {
e.hash= null == e.key ? 0: hash(e.key);
}int i =indexFor(e.hash, newCapacity);//将当前entry的next链指向新的索引位置,newTable[i]有可能为空,有可能也是个entry链,如果是entry链,直接在链表头部插入。
e.next =newTable[i];
newTable[i]=e;
e=next;
}
}
}
以上内容是从别人文字copy过来的。
下面是我的代码流程推演:
tableold【0】进行遍历,copy到新的table中
第一次遍历:tableold【0】的链表上第一个元素是(key:3,value:A,next:(key:7,value:B)),
通过这个行代码:
e.next =newTable[i];
然后原table的第二个链表的第一个元素变成:(key:3,value:A,next:null),然后copy到新的table中
新table【3】变为:(key:3,value:A,next:null)
对应上面:
第二次遍历,当前元素是(key:7,value:B,next:(key:5,value:C)),同样运行代码:
e.next = newTable[i];
当前元素(第二个元素),变成(key:7,value:B,next:(key:3,value:A,next:null)),因为第一个元素,和第二个元素获取下标一样,
数组【3】位置变成(key:7,value:B,next:(key:3,value:A,next:null))
对应图中:
jdk1.8中hashmap
1.扩容在添加元素之后
2.关于红黑树,如果总元素小于64,及时链表达到了if(>=7)也使用单链表,这种情况也会发生扩容。
3.达到闸阀也会发生扩容。
参考:http://m.mamicode.com/info-detail-2120749.html
https://blog.csdn.net/woshimaxiao1/article/details/83661464
https://www.cnblogs.com/yanzige/p/8392142.html经典
https://www.cnblogs.com/shianliang/p/9233199.html jdk1.8扩容