狂啃HashMap resize 函式

2021-10-06 08:04:49 字數 2751 閱讀 7918

/**

* 初始化或翻倍table的大小,如果table還未被初始化

* 為null時,則分配threshold的值給table的初始化大小

* 否則,由於是根據2的次冪擴容,每個桶中的元素不是在相同

* 的下標,就是在新的雜湊表中2的次冪的下標中

* @return the table

*/final node

resize()

// 擴容為原來兩倍

elseif(

(newcap = oldcap <<1)

< maximum_capacity &&

oldcap >= default_initial_capacity)

newthr = oldthr <<1;

}// oldcap = 0 oldthr > 0:執行有參的建構函式走到這

else

if(oldthr >0)

newcap = oldthr;

// oldcap = 0 oldthr = 0:執行無參的建構函式走該分支

else

// 執行的是有參建構函式進入該if分支

if(newthr ==0)

// threshold設定完成

threshold = newthr;

// 建立擴容後的新的雜湊表

node

newtab =

newnode

[newcap]

; table = newtab;

if(oldtab != null)

else

if(e instanceof

treenode)(

(treenode

)e).

split

(this

, newtab, j, oldcap)

;else

//轉移到新的bin

else

else

hitail = e;}}

while

((e = next)

!= null)

;// 斷開tail的next指標 設定下標

if(lotail != null)

// 移到j+oldcap的位置

if(hitail != null)}}

}}return newtab;

}

e.hash & (newcap - 1):由於newcap只能為2的次冪,因此與hash值作與運算只會產生兩種結果,一種是0,一種是oldcap將結果為0或oldcap的節點分別用兩組(每組一對頭尾指標)指標儲存對應的順序,調整好後,將為0的首節點放置在當前下標i保持不變,為oldcap的首節點移動到newtab[i + oldcap]中

初始化時,若通過有參建構函式構造,預設建立大於等於當前傳入引數的最小的2次冪大小最小容量為2,若通過無參建構函式構造,則預設建立容量為16每次擴容為原來的兩倍(oldcapacity << 1)

void

resize

(int newcapacity)

// 初始化新陣列

entry[

] newtable =

newentry

[newcapacity]

;boolean oldalthashing = usealthashing;

usealthashing |= sun.misc.vm.

isbooted()

&&(newcapacity >= holder.alternative_hashing_threshold)

;boolean rehash = oldalthashing ^ usealthashing;

// 將舊陣列中的entry轉移到新陣列中

transfer

(newtable, rehash)

; table = newtable;

threshold =

(int

)math.

min(newcapacity * loadfactor, maximum_capacity +1)

;}/** * transfers all entries from current table to newtable.

*/void

transfer

(entry[

] newtable,

boolean rehash)

// 取模求出下標

int i =

indexfor

(e.hash, newcapacity)

;// 若發生碰撞,頭插法插入element

e.next = newtable[i]

; newtable[i]

= e;

e = next;}}

}/**

* returns index for hash code h.

*/static

intindexfor

(int h,

int length)

由於頭插法會改變原有的鍊錶順序,導致指標反轉,多執行緒情況下可能會造成環形鍊錶資料丟失

參考

北大除了「啃老」還能「啃」什麼

王學進 北大除了 啃老 還能 啃 什麼 近日,北大和耶魯大學的校園宣傳片因風格迥異引起熱議,部分認為北大宣傳片 拍攝跑偏 成了風景名勝片,而耶魯宣傳片更關注人。對此,拍攝宣傳片的北大藝術學院副教授陳宇稱,北大宣傳片旨在反映中國文人薪火相傳的精神氣質,與耶魯大學的招生宣傳不同,兩者沒有可比性。2月 1...

JDK13 HashMap resize原始碼解析

resize是重新雜湊,所以要在現在容量和閾值的基礎上獲取新的容量和閾值,函式首先進行了變數定義 final hashmap.node resize else if newcap oldcap 1 maximum capacity oldcap default initial capacity de...

JDK1 8 HashMap resize原始碼解讀

final node resize newcap oldcap 2 左移1位相當於原值 2 並且原長度大於16 else if newcap oldcap 1 maximum capacity oldcap default initial capacity newthr oldthr 1 doubl...