真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何解析Java8HashMap擴(kuò)容算法-創(chuàng)新互聯(lián)

本篇文章為大家展示了如何解析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[] resize() {   // ...省略不重要的 }

其中,當(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 e;  if ((e = oldTab[j]) != null) {    oldTab[j] = null;    if (e.next == null)      newTab[e.hash & (newCap - 1)] = e;    else if (e instanceof TreeNode)      ((TreeNode)e).split(this, newTab, j, oldCap);    else { // preserve order      Node loHead = null, loTail = null;      Node hiHead = null, hiTail = null;      Node next;      do {        next = e.next;        if ((e.hash & oldCap) == 0) {          if (loTail == null)            loHead = e;          else            loTail.next = e;          loTail = e;        }        else {          if (hiTail == null)            hiHead = e;          else            hiTail.next = e;          hiTail = e;        }      } while ((e = next) != null);      if (loTail != null) {        loTail.next = null;        newTab[j] = loHead;      }      if (hiTail != null) {        hiTail.next = null;        newTab[j + oldCap] = hiHead;      }    }  }}final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {  // ...省略不重要的  if ((p = tab[i = (n - 1) & hash]) == null)    tab[i] = newNode(hash, key, value, null);  else {  // ...省略不重要的}

像我們看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è)資訊頻道。


當(dāng)前文章:如何解析Java8HashMap擴(kuò)容算法-創(chuàng)新互聯(lián)
分享路徑:http://weahome.cn/article/cchcso.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部