hashMap基礎原始碼解析

2021-10-22 17:16:10 字數 1965 閱讀 6910

2.hashmap基礎原始碼解析

鍊錶調整為紅黑樹的鍊錶長度閾值是什麼?

紅黑樹調整為鍊錶的鍊錶長度閾值是什麼?

鍊錶調整為紅黑樹的陣列最小閾值是什麼?

hashmap的陣列table儲存的就是乙個個的node型別,很清晰地看到有一對鍵值,還有乙個指向next的指標(以下只擷取了部分原始碼):

copystatic class

node

implements

map.entry

之前的**中在new物件時呼叫的是hashmap的無參構造方法,進入到該構造方法的原始碼檢視一下:

copypublic hashmap()

發現沒什麼內容,只是賦值了乙個預設載入因子;而在上文我們觀察到原始碼中table和size都沒有賦予初始值,說明剛建立的hashmap物件沒有分配容量,並不擁有預設的16個空間大小,這樣做的目的是為了節約空間,此時table為null,size為0。

當我們往物件裡新增元素時呼叫put方法:

copypublic v put

(k key, v value)

put方法把key和value傳給了putval,同時還傳入了乙個hash(key)所返回的值,這是乙個產生雜湊值的方法,再進入到putval方法(部分原始碼):

copyfinal v putval

(int hash, k key, v value,

boolean onlyifabsent,

boolean evict)

}

這裡面建立了乙個tab陣列和乙個node變數p,第乙個if實際是判斷table是否為空,而我們現在只關注剛建立hashmap物件時的狀態,此時tab和table都為空,滿足條件,執行內部**,這條**其實就是把resize()所返回的結果賦給tab,n就是tab的長度,resize顧名思義就是重新調整大小。檢視resize()原始碼(部分):

copyfinal node

resize()

@suppresswarnings()

node

newtab =

(node

)new

node

[newcap]

; table = newtab;

return newtab;

}

該方法首先把table及其長度賦值給oldtab和oldcap;threshold是閾值的意思,此時為0,所以前兩個if先不管,最後else裡newcap的值為預設初始化容量16;往下建立了乙個newcap大小的陣列並將其賦給了table,剛建立的hashmap物件就在這裡獲得了初始容量。然後我們再回到putval方法,第二個if就是根據雜湊碼得到的tab中的乙個位置是否為空,為空便直接新增元素,此時陣列中無元素所以直接新增。至此hashmap物件就完成了第乙個元素的新增。當新增的元素超過16*0.75=12時,就會進行擴容:

copyfinal v putval

(int hash, k key, v value,

boolean onlyifabsent,

boolean evict)

擴容的**如下(部分):

copyfinal node

resize()

elseif(

(newcap = oldcap <<1)

< maximum_capacity &&

oldcap >= default_initial_capacity)

}}

核心部分是else if裡的移位操作,也就是說每次擴容都是原來大小的兩倍

注*:額外說明的一點是在jdk1.8以前鍊錶是頭插入,jdk1.8以後鍊錶是尾插入。

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 ...