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扩容

原文地址:https://www.cnblogs.com/longsanshi/p/13595114.html