HashMap的put和get的底層實現原理

2021-10-08 03:56:31 字數 2326 閱讀 8106

hashmap的put和get的底層實現原理

在了解hashmap的底層實現原理的時候,我們首先了解hashmap的底層結構。

hashmap的底層是基於陣列+鍊錶實現的。但是jdk1.7和jdk1.8的實現有點不同。

hashmap的儲存結構:

hashmap的底層是基於陣列+鍊錶實現的。但是jdk1.7和jdk1.8的實現有點不同。

hashmap的儲存結構:

1.hashmap底層是以陣列方式進行儲存。將key-value對作為陣列中的乙個元素進行儲存。

2.key-value都是map.entry中的屬性。其中將key的值進行hash之後進行儲存,即每乙個key都是計算hash值,然後再儲存。每乙個hash值對應乙個陣列下標,陣列下標是根據hash值和陣列長度計算得來。

3.由於不能保證兩個不同的key有相同的hash值,即該位置的陣列中的元素出現兩個,對於這種情況,hashmap採用鍊錶形式進行儲存。

基本構造:

1.初始化桶大小,因為底層是陣列,所以這是陣列預設的大小。

2.桶最大值。

3.預設的負載因子(0.75)

4.table 真正存放資料的陣列。

5.map 存放數量的大小。

6.桶大小,可在初始化時顯式指定。

7.負載因子,可在初始化時顯式指定。

hashmap的預設容量為16,負載因子是0.75,當我們在使用hashmap的時候,不斷給hashmap中存放值,當數量達到了12(16*0.75)的時候,就需要進行擴容,擴容涉及到了rehash複製資料等操作,所以擴容會消耗資源。因此我們在使用的時候,可以提前預估hashmap的容量最好。

put的底層實現原理:

首先我們去判斷當前陣列是否需要初始化,如果不需要初始化,就判斷key值是否為空,如果為空,那就直接put乙個空值進去,然後根據key去計算hashcode值,這樣的話我們就可以知道索引的下標(元素存放位置),如果那個位置是 乙個鍊錶則需要遍歷判斷裡面的 hashcode、key 是否和傳入 key 相等,如果相等則進行覆蓋,並返回原來的值如果當前位置沒有元素,那就直接新增乙個entry物件到當前位置(呼叫addentity寫入entity時需要判斷是否需要擴容)。

get的底層實現原理:

首先也是根據 key 計算出 hashcode,然後定位到具體的桶中。

判斷該位置是否為鍊錶。

不是鍊錶就根據 key 的 hashcode 是否相等來返回值。

為鍊錶則需要遍歷直到 key 及 hashcode 相等時候就返回值。

啥都沒取到就直接返回 null

jdk1.7的缺點:當hash衝突嚴重時,形成的鍊錶會越來越長,這樣的話,查詢的效率會越來越低。

因此在jdk1.8中進行了優化。

jdk1.8:

put的底層實現原理:

1.判斷當前桶是否為空,空的就需要初始化(resize 中會判斷是否進行初始化)。

2、根據當前 key 的 hashcode 定位到具體的桶中並判斷是否為空,為空表明沒有 hash 衝突就直接在當前位置建立乙個新桶即可。

3、如果當前桶有值( hash 衝突),那麼就要比較當前桶中的 key、key 的 hashcode 與寫入的 key 是否相等,相等就賦值給 e,在第 8 步的時候會統一進行賦值及返回。

4、如果當前桶為紅黑樹,那就要按照紅黑樹的方式寫入資料。

5、如果是個鍊錶,就需要將當前的 key、value 封裝成乙個新節點寫入到當前桶的後面(形成鍊錶)。6、接著判斷當前鍊錶的大小是否大於預設的閾值,大於時就要轉換為紅黑樹。

7、如果在遍歷過程中找到 key 相同時直接退出遍歷。

8、如果 e != null 就相當於存在相同的 key,那就需要將值覆蓋。

9、最後判斷是否需要進行擴容。

get方法的底層實現原理:

1、首先將 key hash 之後取得所定位的桶。

2、如果桶為空則直接返回 null 。

3、否則判斷桶的第乙個位置(有可能是鍊錶、紅黑樹)的 key 是否為查詢的 key,是就直接返回 value。

4、如果第乙個不匹配,則判斷它的下乙個是紅黑樹還是鍊錶。

5、紅黑樹就按照樹的查詢方式返回值。

6、不然就按照鍊錶的方式遍歷匹配返回值。

hashmap的遍歷方式:entryset(推薦使用,因此使用entryset遍歷後,可以取出key和value)、keyset(需要通過key來取出value)等等方法

hashmap 的put與get 筆記

put操作 成員變數 transient entry table entry empty table 陣列 1 資料介面就是陣列 加鍊表 hashmap有 table陣列專門記錄 的就是,正常的put值就是計算出key的hashcode然後找出索引 i 去table陣列中找,如果存在就用單鏈表儲存,...

HashMap原始碼之get與put方法

hashmap是基於陣列和鍊錶來儲存鍵值對物件的,我們簡單看下get和put方法的原始碼。1 我們呼叫put方法來儲存鍵值對時,它先呼叫hash方法來計算hashcode,然後用hashcode和entry陣列的大小來做按位與操作,求出所在的entry陣列的下標位置。通過key與下標所在的entry...

HashMap的Put方法(二)

hashmap類中有如下put方法 方法體省略 public v put k key,v value final v putval int hash,k key,v value,boolean onlyifabsent,boolean evict public void putall map ext...