JDK13 HashMap resize原始碼解析

2021-10-01 14:58:13 字數 1560 閱讀 1402

resize是重新雜湊,所以要在現在容量和閾值的基礎上獲取新的容量和閾值,函式首先進行了變數定義

final hashmap.node resize() 

else if ((newcap = oldcap << 1) < maximum_capacity &&

oldcap >= default_initial_capacity)//default_initial_capacity= 1<<4 = 16

newthr = oldthr << 1;

//左移一位是double,newcap和newthr都變成double

}//下面oldcap = 0,對table進行初始化,確定初始的容量和閾值

else if (oldthr > 0)

newcap = oldthr;//原來求的閾值賦值給新容量

else

if (newthr == 0)

//將 新容量*輸入的loadfactor 的值賦給新閾值,完成初始化

threshold = newthr;

確定新的table的容量和閾值之後,如果原來已儲存資料,需要對原來的資料重新雜湊,使分布均勻,這是jdk8之後對jdk7的優化,不會使鍊錶越來越長

hashmap.node newtab = (hashmap.node)new node[newcap];//產生乙個新的node陣列

table = newtab;//這一句說明只要初始化一次之後,table就不可能為0

if (oldtab != null) while ((e = next) != null);

if (lotail != null)

if (hitail != null) }}

}}

return newtab;

do···while函式就是把乙個桶對應的鍊錶上的每乙個節點,利用e.hash & oldcap的值,把原來的乙個鍊錶拆成兩個鍊錶

do 

else

} while ((e = next) != null);

e.hash & oldcap 其實是取出e.hash上的乙個標誌位,因為oldcap總是2的某次方,所以oldcap用位表示是00xx10xx0的形式。

在e.hash中,oldcap中1對應的那一位,e.hash可能為0,可能為1

如果這一位是0,那麼e.hash & (oldcap-1)就等於e.hash & (newcap-1)

如果這一位是1,那麼於e.hash & (newcap-1)=e.hash & (oldcap-1)+oldcap

通過這種方法,把鍊錶上的節點分到兩個新的鍊錶中,乙個是lo鍊錶,乙個是hi鍊錶

當這個鍊錶上所有的節點都被分配完之後,再把新生成的鍊錶放進newtab的桶裡

if (lotail != null) 

if (hitail != null)

使用(e.hash & oldcap) == 0來進行分配的原因:可以參考

JDk原始碼解析之四 Vector原始碼解析

具體的三個屬性 解釋看圖中注釋。vector沒有採取arraylist臨界值擴容的辦法,而是每次不夠的時候,直接根據capacity的值來增加。具體怎麼增加後面會說。vector的構造方法如下。簡單粗暴,如果呼叫無參建構函式,直接就將初始容量設定成了10,最終在右側的構造方法裡,將陣列的長度設定為1...

JDK 原始碼 閱讀

to be continuing.持續修改中。1.stringbuffer 所處類層次 易忽略點 這個類是執行緒安全的。所有的method直接或間接加synchronized。所以我們如果是單執行緒情況下也考慮到這個會不會影響到效率。當然可能jit可以進行這個優化,待我接下來驗證。預設情況下乙個長為...

原始碼解析 JDK原始碼之LinkedHashMap

linkedhashmap原始碼,基於 jdk1.6.43 他繼承了hashmap,並且實現了插入和訪問的有序功能 public class linkedhashmapextends hashmapimplements map 其也有乙個entry內部類,繼承了 hashmap 的entry 內部類...