hashmap原始碼分析jdk8

2021-07-29 17:55:39 字數 1750 閱讀 1503

最近看了下jdk8的hashmap原始碼,相比於7,在儲存結構上有了些改變。

1.在jdk8之前,hashmap的儲存結構是陣列+鍊錶的形式,那麼這種方式隨著鍊錶的長度增加,效率也凸顯出來。

所以在jdk8中這塊做了優化,當鍊表超過一定長度時轉化為紅黑樹來解決這個問題,下面用流程圖畫出hashmap

的put方法實現邏輯。

下面請帶著這些問題看原始碼,為什麼樹的查詢效率比煉表高,達到什麼樣的條件會擴容,為什麼擴容會影響效率

呢,怎樣實現鍊錶到樹的轉化?

2.先來看下put方法原始碼。

public v put(k key, v value)

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

boolean evict)

v oldvalue = e.value;

if (!onlyifabsent || oldvalue == null)

e.value = value;

afternodeaccess(e);

return oldvalue;}}

++modcount;

//threshold=newthr:(int)(default_load_factor * default_initial_capacity);

//預設0.75*16,大於threshold值就擴容

if (++size > threshold)

resize();

afternodeinsertion(evict);

return null;

1 final

node resize() 12

// 沒超過最大值,就擴充為原來的2倍 13

else

if((newcap = oldcap << 

1) < maximum_capacity && 14

oldcap >= default_initial_capacity) 15

newthr = oldthr << 1; 

// double threshold 16

} 17else

if(oldthr > 0) 

// initial capacity was placed in threshold 18

newcap = oldthr; 19

else 23

// 計算新的resize上限 24

if(newthr == 0)

30threshold = newthr; 31

@suppresswarnings()

32node newtab = (node)

newnode[newcap]; 33

table = newtab; 34

if(oldtab != 

null)

58// 原索引+oldcap 59

else 66

} while

((e = next) != 

null);

67// 原索引放到bucket裡 68

if(lotail != 

null)

72// 原索引+oldcap放到bucket裡 73

if(hitail != 

null)

77} 78

} 79}

80}

81return

newtab; 82

}

分析HashMap 的 JDK 原始碼

緣由 今天好友拿著下面的 問我為什麼 map.entry 這個介面沒有實現 getkey 和 getvalue 方法,卻可以使用,由此,開啟了一番查閱 jdk 原始碼的旅途 map map new hashmap map.put 1,張三 map.put 2,李四 map.put 3,王五 map....

HashMap原始碼分析 JDK1 8

陣列 鍊錶 紅黑樹 陣列儲存元素,當有衝突時,就在該陣列位置形成乙個鍊錶,儲存衝突的元素,當鍊表元素個數大於閾值時,鍊錶就轉換為紅黑樹。transient node table transient int size int threshold final float loadfactor 預設初始容...

HashMap原始碼分析 (JDK1 8

首先,hashmap儲存結構類似於位桶,總體結構是 位桶 鍊錶 紅黑樹,這與之前版本的實現有所改進。常量域預設容量16 static final int default initial capacity 1 4 最大容量2的30次方 static final int maximum capacity...