原始碼解析 HashMap擴容 紅黑樹單獨講

2021-10-19 07:35:25 字數 1471 閱讀 9259

1.擴容的方法如下,主要幹這幾件事情,第一件,算出新陣列長度和新陣列擴容閾值,建立新陣列。第二件,擴容前的陣列元素遷移到擴容後的陣列當中去。主要分為單個元素的遷移,鍊錶的遷移,紅黑樹的遷移(下期再講),下面我們依次來看一下hashmap它是怎麼玩的吧。

首先我們看下新陣列長度和新陣列擴容閾值是怎麼算出來的。這裡也分為兩種情況,第一種是陣列已經初始化過了。第二種是hashmap裡面的雜湊表為null的情況。先看下陣列已經初始化過的情況。如下圖所示。

先判斷,擴容前陣列長度是否已經達到最大值,如果達到了最大值,則不擴容了,並設定擴容條件為最大值,返回擴容前的陣列。一般這種情況比較少見。

如果是正常情況,則先把老陣列擴容1倍,賦值給新陣列長度的變數,賦值後,判斷是否小於長度最大值並且老陣列長度要大於等於16,滿足以上條件後,新陣列的擴容閾值為擴容之前的2倍。

然後我們再看下ashmap裡面的雜湊表為null的情況. 如果老陣列的擴容閾值大於0,則把老陣列的擴容閾值賦值給新陣列的長度 ,如果是老陣列的長度和老陣列的擴容閾值都為0的時候,則設定預設值,newcap=16,newthr=16*0.75.

如果新陣列的擴容閾值等於0,則設定它的擴容閾值。設定完以後,建立新的陣列並且長度為newcap。

接下來就是資料遷移的過程了。先判斷老陣列是否為空,不為空則開始資料遷移。迴圈陣列中的每個元素,如果是單個元素,先把陣列下標的值設為null,方便jvm**,然後根據e.hash & (newcap - 1)算出新陣列的下標位置,直接遷移到新陣列。

如果是鍊錶,則有高位鏈和低位鏈,先根據e.hash & oldcap算出當前節點的高位是0還是1,如果是0,則把當前節點放入低位鏈,如果為1,則把當前節點放入高位鏈。

鍊錶遍歷完以後,判斷高低位鍊錶是否為空,低位鍊錶不為空,則把lotail.next = null並且新陣列的同乙個下標指向該低位鏈。高位鏈不為空,則把hitail.next = null,然後新陣列j + oldcap的下標位置指向該高位鏈。遷移結束,返回新陣列。紅黑樹遷移,下期再講。

HashMap原始碼解析

以jdk1.8為例,hashmap是乙個用於儲存key value鍵值對的集合,每乙個鍵值對是乙個node jdk1.7叫做entry 後台是用乙個node陣列來存放資料,這個node陣列就是hashmap的主幹。這裡我們主要來分析hashmap的get和put方法。public v put k k...

hashMap 原始碼解析

這幾天跳槽 被人問得最多的問題就是基礎方面的知識.當時學習的時候有點囫圇吞棗.現在回頭把這些基本的集合類原始碼都仔細閱讀下 hashmap 用的是最頻繁的.所以問得也最多了.initcapacity 初始化的容量 loadfacotr 負載因子 主要用來計算threshold的值 threshold...

HashMap原始碼解析

預設字段 static final int default initial capacity 1 4 預設node的陣列長度 16 static final int maximum capacity 1 30 陣列的最大長度 2 30 static final float default load ...