面試題 說說HashMap是如何進行擴容的?

2021-10-11 09:43:57 字數 2273 閱讀 8695

hashmap擴容:兩倍擴容,底層為陣列,當陣列滿了之後,會自動擴容。

擴容:擴大陣列長度,對原陣列進行rehash操作,把原陣列copy到新陣列中

問題:假設16陣列中[<>]同乙個位置存放了多對key-value,當擴容為32位時,其中某對或多對key-value發生了位置的變動。

擴容後,要進行rehash重新將hash值與n-1進行與運算。如下

陣列長度=16

n-1 0000 0000 0000 0000 0000 0000 0000 1111

hash1 1111 1111 1111 1111 0000 1111 0000 0101

&結果 0000 0000 0000 0000 0000 0000 0000 0101

&結果=5(index為5的位置)

n-1 0000 0000 0000 0000 0000 0000 0000 1111

hash2 1111 1111 1111 1111 0000 1111 0001 0101

&結果 0000 0000 0000 0000 0000 0000 0000 0101

&結果=5(index為5的位置)

在陣列長度為16的時候,兩個hash值的位置是一樣的,用鍊錶來進行處理,出現乙個hash衝突的問題

如果陣列長度擴容之後為32,重新對每個hash值進行定址,也就是用每個hash值跟新陣列的length-1進行與操作

陣列長度=32

n-1 0000 0000 0000 0000 0000 0000 0001 1111

hash1 1111 1111 1111 1111 0000 1111 0000 0101

&結果 0000 0000 0000 0000 0000 0000 0000 0101

&結果=5(index為5的位置)

n-1 0000 0000 0000 0000 0000 0000 0001 1111

hash2 1111 1111 1111 1111 0000 1111 0001 0101

&結果 0000 0000 0000 0000 0000 0000 0001 0101

&結果=21(index為21的位置)

判斷二進位制結果中是否多出乙個bit的1,如果沒有,那麼就是原來的index,如果多了出來,那麼就是index+oldcap,通過這個方式,就避免了rehash的時候,用每個hash對新陣列.length取模,取模效能不高,位運算的效能比較高。

rehash實際上去去將原來的index位置加上原來的陣列長度,如上:5+16=21

1.面試題:為什麼陣列容量會是2的倍數,以及擴容為什麼是擴成兩倍?

可以減少碰撞機率,2的倍數 -1 得到值所有位都是1,和計算值相與後能保證結果單一,如果位上的0越多,碰撞概率越大。

比如容量是2的4次方 減1就是 1111.。。那麼計算值1110過來和他相與, 結果是1110,另乙個計算值1111和他相與結果仍是1111 各自結果不一樣 不會碰撞 如果容量不是2的4次方 比如15 減1就是1110. 那麼計算值1110過來和他相與, 結果是1110,另乙個計算值1111和他相與結果是1110 跟前乙個一樣 發生碰撞了

2.面試題:擴容和負載因子之間的關係,元素達到多少擴容2倍,怎麼算的?

容量*負載因子 預設長度16的hashmap,負載因子預設0.75所以達到12時會擴容。12代表的是hashmap中元素的總數,即size()方法的返回值

3.如果是hash碰撞,後加入的值是加入在煉表頭還是鍊錶尾呢?

看jdk原始碼,1.7是表頭,1.8是表尾。表頭插入會導致死迴圈的問題,造成cpu百分百

4.rehash邏輯

如果該桶單元只有乙個資料:直接e.hash & (newcap - 1)重新計算新桶的位置

如果該桶單元是乙個鍊錶:(e.hash & oldcap) == 0 根據與舊桶的容量,判斷在新桶中的位置是原位置,還是原位置+oldcap,鍊錶順序不變,分成兩部分,一部分放到新桶中原位置,一部分放到新桶中原位置+oldcap,可以看到這裡並不是避免了定位的與運算,而是避免了鍊錶資料進入新桶多次的hash衝突。

如果該桶單元是乙個紅黑樹:(e.hash & bit) == 0與桶單元是鍊錶邏輯類似,判斷在新桶中的位置是原位置,還是原位置+oldcap,紅黑樹順序不變,分成兩部分,一部分放到新桶中原位置,一部分放到新桶中原位置+oldcap,同時將根節點放到桶單元中會判斷樹中資料長度,小於等於6轉換成鍊錶。原理一致,多了轉換成鍊錶的判斷。

面試題 HashMap詳解

先上hashcode和equals原始碼 jni,呼叫底層其它語言實現 public native inthashcode 預設同 直接比較物件 public boolean equals object obj equals方法 string類中重寫了equals方法,比較的是字串值,看一下原始碼實...

HashMap常見面試題

1.你知道hashmap的工作原理嗎?你知道hashmap的get 方法的工作原理嗎?hashmap基於hashing原理,我們通過put 和get 方法儲存和獲取物件。當我們將鍵值對傳遞給put 方法時,它呼叫鍵物件的hashcode 方法來計算hashcode,讓後找到bucket位置來儲存en...

HashMap常見的面試題

1.hashmap底層是如何實現的?首先底層資料結構是由陣列 鍊錶組成鍊錶雜湊。hashmap先得到key的雜湊值,在通過擾動函式 減少碰撞次數 得到hash值,接著通過hash n 1 n位table的長度,運算後得到陣列的索引值。如果當前節點存在元素,則通過比較hash值和key值是否相等,相等...