hashmap扩容理解
以下内容基于jdk1.7,关于hashmap在jdk1.8中的内容参考
https://www.cnblogs.com/yanzige/p/8392142.html
在添加元素的时候,如果元素大于等于闸阀,同时即将发生碰撞,hashmap会进行扩容:
扩容的时候,会创建新的table来装旧table的元素。
方法如下:
void transfer(Entry[] newTable, boolean rehash) { int newCapacity = newTable.length; //for循环中的代码,逐个遍历链表,重新计算索引位置,将老数组数据复制到新数组中去(数组不存储实际数据,所以仅仅是拷贝引用而已) for (Entry<K,V> e : table) { while(null != e) { Entry<K,V> 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扩容