HashMap底層實現原理
JDK7中底層實現原理
HashMap map = new HashMap();
在例項化以後,底層建立了長度為16的一維陣列Entry[] table
.....已經執行過put操作.....
map.put(key1 , value1);
呼叫key1所在類的hashCode(),計算key1雜湊值,此雜湊值經過某種演算法計算後,得到在Entry陣列中的存放位置
- 如果此位置上為空,此時的key1-value1新增成功(存放的是entry,而entry裡面有key和value)
- 如果此位置上不為空(此位置上存在一個或多個資料(以連結串列形式存在)),比較當前key1和已經存在的資料的雜湊值
- 如果key1的雜湊值與已經存在的資料的雜湊值都不相同,此時key1-value1新增成功
- 如果key1的雜湊值與已經存在的某一個資料的雜湊值都相同,呼叫key1所在類的equals()方法,進行比較
- 如果equals()方法返回false,此時key1-value新增成功
- 如果equals()方法返回true,使用value1替換相同的key的value值(修改的功能)
大致過程與HashSet類似
(具體的圖解可跳轉到如下網址)
https://www.cnblogs.com/CrabDumplings/p/13390443.html
注意:
雜湊值不同的新增成功情況和equals()返回false新增成功的兩種情況下:
此時key1-value1和原來的資料以連結串列的方式儲存
在不斷的新增過程中,會涉及擴容問題,當超出臨界值且要存放的位置非空時,需要擴容
預設的擴容方式:擴容到原來容量的2倍,並將資料複製過來
JDK8中底層實現原理
相較於jdk7,在底層實現方面的不同如下
HashMap map = new HashMap();
- 底層沒有建立一個長度為16的陣列
- jdk8底層的陣列:Node[],而非Entry[]陣列
map.put(key1 , value1);
-
首次呼叫put方法時,底層建立長度為16的陣列
-
jdk7底層結構:陣列 + 連結串列
jdk8底層結構:陣列 + 連結串列 + 紅黑樹
當陣列的某一個索引位置上的元素以連結串列形式存在的資料個數大於8且當前陣列的長度超過64,此時此索引位置上的所有資料改為使用紅黑樹儲存
原始碼中出現的概念
- DEFAULT_INITIAL_CAPACITY:HashMap的預設容量16
- DEFAULT_LOAD_FACTOR:HashMap的預設載入因子:0.75
- threshold:擴容臨界值,容量 * 填充因子——16 * 0.75 = 12
- TREEIFY_THRESHOLD:Bucket中連結串列長度大於該預設值,轉化為紅黑樹——8
- MIN_TREEIFY_CAPACITY:桶中的Node被樹化時最小的hash表容量——64