以下內容基於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擴容