HashMap底層實現原理及測試

2021-10-22 06:35:19 字數 2333 閱讀 1685

/**

* @description:

* 本案例用於測試hashmap何時擴容,擴容時是怎麼rehash的,何時轉紅黑樹 (條件key=key+16)

* 本案例以最少的元素個數(9個)觸發擴容,(條件 key=key+16)

* 以最少的元素個數(11個)觸發轉紅黑樹 (條件key=key+128)

* @author: [email protected]

* @date: 2021/3/15 14:11

* @param:

*/public class testhashmap

public static void main(string args) }}

2.1、當map中的陣列為空,也就是第一次插入時建立乙個長度16的陣列;

2.2、當map.size+1>閾值,也就是元素個數等於陣列的長度乘以存放比例;

2.3、當陣列中某個位置鍊錶長度為9,且陣列長度小於64,即使不滿足map.size+1>閾值的條件也會觸發擴容。

**中陣列插入時下標i = (n - 1) & hash,擴容時i=e.hash & (newcap - 1)和插入時邏輯完全一樣,即陣列長度減1與運算上key的hash值,這裡非常奇妙,n=16則i = hash的後四位,n=32則i=hash的後5位,n=64則i=hash的後6位。

從這裡可以很容易理解當陣列擴容時,原來存在i位置的值要麼不動(公升位為0),要麼變為n+i(公升位為1)。

例如0和16二進位制分別是 00000,10000,當陣列長度為16時只需要看後4位都是0000,都存在i=0的位置,當陣列擴容

到32時,0的公升位是0還存在i=0的位置,16的公升位為1存到i = 0+16=16的位置。

這就是為什麼每次擴容都是原來2倍的原因,不需要rehash,只需要看公升位,公升位0則不動 ,公升位1則i = n+i 

轉紅黑樹的條件:鍊錶插入第9個元素,且陣列長度不小於64

由下圖可以看出  鍊錶已有有8個node,插入第九個元素時並將第八個元素的next指向第九個元素之後,觸發發轉紅黑樹第乙個條件,也就是說鍊錶長度為9才轉紅黑樹。

由下圖當陣列的長度小於64時,會先擴容陣列,不轉紅黑樹,即使本實驗中只有tab[0]中有資料,其它15的位置都是空,

第一次進入轉紅黑樹的方法,擴容,長度16變32

第二次進入轉紅黑樹的方法,擴容:長度32變64

第三次進入轉紅黑樹的方法才轉紅黑樹

由下圖第33個才開始轉,為什麼呢?

第一次擴容時i=0的位置9個元素;擴容後i=0的5個 ,i=16的4,

第二次擴容時i=0的位置9個元素,i=16的位置8個,擴容後 i=0的位置5個 ,i=32的位置4個,i=16的位置4個,i=48的位置4個  ,陣列長度已經為64了

最後當4個位置都達到了8個後,當i=0的位置插入第9個元素,也就是總的第33個元素時,將i=0位置的鍊錶轉化為紅黑樹

那麼不讓資料重分布,則可得出最少需要多少元素 。可以推測 k=k+128資料不會重分布,可得到最少需要11個元素轉紅黑樹成功。

hashmap底層實現原理

每次初始化hashmap都會構造乙個table陣列,而table陣列的元素為entry節點。static class entryimplements map.entryhashmap也可以說是乙個陣列鍊錶,hashmap裡面有乙個非常重要的內部靜態類 entry,這個entry非常重要,它裡面包含了...

HashMap底層實現原理

hashmap map new hashmap 在例項化以後,底層建立了長度為16的一維陣列entry table 已經執行過put操作.map.put key1 value1 呼叫key1所在類的hashcode 計算key1雜湊值,此雜湊值經過某種演算法計算後,得到在entry陣列中的存放位置 ...

HashMap底層實現原理

一 jdk1.7中hashmap的底層實現原理 首先,當我們通過hashmap的構造方法建立乙個hashmap物件時,底層就會建立乙個entry型別的一維陣列 預設初始化長度為16 當我們執行put操作的時候,會呼叫key所屬類的hashcode方法計算出key的hash值,然後將hash值通過雜湊...