在調用put方法時時,有幾個關鍵點需要考慮:
-
哈希沖突的發生與解決:
- 哈希沖突指不同的鍵通過哈希函數計算得到相同的哈希值,導致它們應該存放在哈希表的同一個位置。解決沖突的常用方法包括開放尋址法和鏈表法(或其升級形式紅黑樹)。
-
HashMap的存儲結構:
- HashMap 的底層數據結構通常是數組加鏈表(或紅黑樹)。數組的每個位置稱為桶(bucket),每個桶存儲一個鏈表(或紅黑樹),用來存放哈希沖突的元素。
-
是否需要擴容:
- 在不同版本的實現中,HashMap 會根據負載因子來判斷是否需要擴容。負載因子是指當前元素個數與數組容量的比值。一般來說,當元素個數超過負載因子乘以數組容量時,就會觸發擴容操作。
-
先添加還是先判斷是否擴容:
- 在 JDK 1.7 和 1.8 中,HashMap 的行為有所不同:
- JDK 1.7:先判斷是否需要擴容,如果需要擴容則擴容到原來的兩倍大小,然后再進行插入操作。
- JDK 1.8:先進行插入操作,然后再判斷是否需要擴容。1.8 引入了紅黑樹結構,當鏈表長度超過一定閾值(默認為8)時,鏈表會轉換為紅黑樹,以提高查詢效率。
- 在 JDK 1.7 和 1.8 中,HashMap 的行為有所不同:
面試回答流程:
一、第一步
首先根據哈希函數計算得出一個哈希值,然后將哈希值與其數組長度-1進行與運算得出他的數組下標。
二、第二部
分情況討論:
當前數組下標位置是否存放了數據,如果為空直接插入即可。
如果不為空,分情況討論:
(1)如果是1.7版本 hashmap的底層是由數組和鏈表結構組成的。并且鏈表中的插入選擇的是頭插法。
首先再1.7中會先進行判斷數組是否需要擴容(數組中元素的個數超過到了負載因子與數組容量的乘積,一般擴容是擴大到原來的二倍),如果超過就先擴容再添加。
(2)1.8版本是先添加后擴容 因為1.8引入了紅黑樹的結構所以要分情況討論
首先要判斷數組下標位置存放數據的結構是紅黑樹還是鏈表
1、鏈表
1.8版本里 對于鏈表的插入 選擇的是尾插法,會一次遍歷整個鏈表,在這個過程中會同時進行比較看鏈表中是否已經存在了相同的key值 ,存在則直接更新對應的value值,不存在則遍歷整個鏈表在末尾插入。這里需要注意的是如果插入之后鏈表的長度超過了8,就會把鏈表轉換成紅黑樹的結構。
2、紅黑樹
如果是紅黑樹的結構會將key和value封裝成一個紅黑樹節點,也是依次遍歷如果存在key則更新value不存在就添加到對應位置。
插入完畢之后,才會考慮是否需要擴容,需要就擴容,不需要就結束put方法。