/**
* 初始化或翻倍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...