本篇文章為大家展示了如何解析Java8 HashMap擴(kuò)容算法,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
東阿ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書合作)期待與您的合作!Java8的HashMap擴(kuò)容過(guò)程主要就是集中在resize()方法中
final Node
其中,當(dāng)HashMap擴(kuò)容完畢之后,需要對(duì)原有的數(shù)據(jù)進(jìn)行轉(zhuǎn)移。因?yàn)槿萘孔兇罅耍糠衷氐奈恢靡虼艘兏?,因而出現(xiàn)了下面的這個(gè)轉(zhuǎn)移過(guò)程。
轉(zhuǎn)移過(guò)程大致是:依次從舊數(shù)組里取值,然后從該值對(duì)應(yīng)的鏈表上依次取出節(jié)點(diǎn),對(duì)節(jié)點(diǎn)取模分別放入lo鏈表和hi鏈表,當(dāng)鏈表中節(jié)點(diǎn)遍歷完后,分別把lo鏈表和hi鏈表放入新數(shù)組的不同位置。
在看到如下第15行時(shí),我在想,為什么(e.hash & oldCap)== 0時(shí)就放入lo鏈表,否則就是hi鏈表?
說(shuō)到這個(gè)問(wèn)題,那我們就要回顧下HashMap存入新元素的過(guò)程了??聪旅娴牡?5行,可以發(fā)現(xiàn)插入時(shí)是使用(n - 1) & hash來(lái)計(jì)算位置的,即數(shù)組長(zhǎng)度-1,而擴(kuò)容移位是使用數(shù)組長(zhǎng)度n計(jì)算的,那這是為什么呢?
for (int j = 0; j < oldCap; ++j) { Node
像我們看Java8的HashMap源碼,應(yīng)該都應(yīng)該知道HashMap的底層數(shù)組長(zhǎng)度都是2的n方的值
那么我們就假設(shè)一個(gè)底層數(shù)組長(zhǎng)度為8的HashMap模擬進(jìn)行插入元素和擴(kuò)容移位的過(guò)程
長(zhǎng)度n=8 ----> 0x1000
n-1 ----> 0x0111
此時(shí)寫入兩個(gè)元素,兩個(gè)元素的hash值分別為hash2 = 0x0101,hash3 = 0x1101
hash2 & n-1 = 0x0101
hash3 & n-1 = 0x0101
兩個(gè)hash取模后的結(jié)果是一致的,所以它們會(huì)在同一個(gè)地方組成鏈表
那么此時(shí)如果要進(jìn)行擴(kuò)容移位呢?
hash2 & n = 0x0000
hash3 & n = 0x1000
此時(shí)兩者的結(jié)果是不一樣的,并且相差0x1000即10進(jìn)制的8即數(shù)組長(zhǎng)度.。
所以這也就是為什么上圖15行只判斷==0的原因,因?yàn)檫@個(gè)取模結(jié)果只有0和1兩種值(數(shù)組長(zhǎng)度是2的n次方,只有除了符號(hào)位外的高位為1)
而兩個(gè)取模結(jié)果等于數(shù)組長(zhǎng)度,這也就是為什么上圖第32和36行那么處理的原因。
上述內(nèi)容就是如何解析Java8 HashMap擴(kuò)容算法,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。