HashMap原始碼(六)

2021-09-26 00:11:40 字數 2081 閱讀 8754

final v putval(int hash, k key, v value, boolean onlyifabsent,

boolean evict)

分析:

1)每次put了乙個key-value對後,就會size++,且會比較size和threshold(陣列的長度 * 負載因子),resize()方法就是在擴容

if (++size > threshold)

resize();

final node resize() 

//省略

threshold = newthr;

@suppresswarnings()

node newtab = (node)new node[newcap];

table = newtab;

if (oldtab != null)

else

} while ((e = next) != null);

if (lotail != null)

if (hitail != null) }}

}}

return newtab;

}

1)新陣列的大小和負載因子是老陣列的2倍

else if ((newcap = oldcap << 1) < maximum_capacity &&

oldcap >= default_initial_capacity)

newthr = oldthr << 1; // double threshold

2)構建新陣列

node newtab = (node)new node[newcap];
3)如果e.next是null,這個位置的元素不是鍊錶,也不是紅黑樹。那麼此時就用e.hash和 (newcap - 1)做與運算,定位並直接放在新陣列裡。

if (e.next == null)

newtab[e.hash & (newcap - 1)] = e;

4)如果該位置是個紅黑樹節點,會呼叫split()方法去遍歷這顆紅黑樹,然後將每個節點重新hash定址,定位找到新陣列。

else if (e instanceof treenode)

((treenode)e).split(this, newtab, j, oldcap);

5)如果不是上面兩種情況,那就是鍊錶。在同乙個鍊錶裡面的資料在擴容以後會雜湊到新陣列的兩個位置,要麼是個index,要麼就是index + oldcap。就相當於原來的乙個鍊錶擴容後變成了兩個鍊錶。

6)這兩個表示rehash後的第1個鍊錶的頭尾指標

nodelohead = null, lotail = null;
7)這兩個表示rehash後的第2個鍊錶的頭尾指標

nodehihead = null, hitail = null;
8)在do-while迴圈中對老煉表中每乙個節點進行遍歷,對每乙個節點的hash值和oldcap做與運算。結果分為0、1兩種情況。為方便講解,假設oldcap=16,即0001 0000。

如果結果為0,表明hash值第5位為0,那麼和(newcap-1)(即31,二進位制0001 1111)做與運算的結果與擴容前和(oldcap -1)(即15,二進位制0000 1111)的結果一樣,也就是這種情況,擴容後到新陣列上還是落在原來的index上。

如果結果為1,表明hash值第5位為1,那麼和(newcap-1)(即31,二進位制0001 1111)做與運算的結果就等於原來的index+oldcap。

if ((e.hash & oldcap) == 0) 

else

9)將上面得到的兩個鍊錶(通過尾部指標判斷是否存在)掛在新的hashmap中。位置分表為index,index+oldcap(原來的位置是index)。

if (lotail != null) 

if (hitail != null)

HashMap原始碼系列 HashMap的屬性

public class hashmap extends abstractmap implements map,cloneable,serializable容載因子 容載因子越大,table陣列中儲存的資料越密集,碰撞的可能性就越大。容載因子越小,儲存越稀疏,碰撞的可能性就越小,不過浪費儲存空間。轉...

HashMap原始碼解讀

一 建立乙個hashmap都做了哪些工作?mapmap new hashmap hahmap無參構造方法 public hashmap 可以看到設定了載入因子 預設0.75 閾值 預設容量16 預設載入因子0.75 12 table是hashmap內部資料儲存結構entry陣列。當hashmap的s...

HashMap原始碼分析

public hashmap int initialcapacity,float loadfactor 2 接下來是重要的put方法,put方法用於將鍵值對儲存到map中,讓我們來具體分析一下。public v put k key,v value if key null 若key為null,則將va...