HashMap 1.8 原始碼分析
1.HashMap的底層資料結構---陣列+單向連結串列
2.一個完整的節點存數資料,在java中一切皆物件,所以在HashMap中應該存在一個類
public class Node{
int hash;
String key;
Object value;
Node next;
}
3.當想要往HashMap中存數資料的時候,肯定需要初始化,初始化時,會遇到幾個問題?
1)要知道陣列的容量是多少
預設大小為:static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
2)需要儲存的資料放到陣列的哪個位置
通過計算hash值來確定位置,java採用的演算法是:
a:如果key = null ,則 hash值為0,
如果key不等於null ,則首先 得到 int h = key.hashCode(),然後讓h的高16位和低16位做異或運算
b:假設陣列的容量是 n = 16,那麼最終的儲存位置 為 (n - 1)&hash<a步驟得到的結果>
說明:如果n = 16 ,那麼 n-1 = 15 其二進位制為 000001111,那麼和這個二進位制&得到的結果永遠只能保留後四位,也就是在0-15之間的數字
由此可以得到結論:HashMap擴容或者初始化一定要是是2的n次方,不然會存在永遠不會儲存資料的位置,極端情況,HashMap變成單向連結串列或者紅黑樹了
3)隨著資料的越來越多,HashMap需要擴容,這個達到什麼標準才會擴容?
在HashMap類中存在一個變數 : int threshold;
這個變數的值等於 陣列的容量*負載因子
說明:當HashMap中節點的數量大於 threshold時,就擴容,重新分配HashMap中的節點
4.當計算得到陣列需要儲存的位置 i 時,會出現兩種情況
1)當前位置 i 還沒有值,那麼直接把資料儲存到這個位置就可以了
2)當前位置已經存在值
a: