HashMap源碼(一) —— 數據結構、put存儲過程介紹

HashMap 數據結構

Jdk1.8之前:數組+鏈表
Jdk 1.8之後 數組+鏈表+紅黑書
鏈表長度大於8後並且數組長度 大於64 鏈表結構轉化成紅黑樹結構

爲什麼jdk8之後要用紅黑樹

 因爲鏈表插入快,查詢慢,當鏈表太長時,
 相當於 node.next.next.next.next.next.next.next.next …… = new Node(xx)
 其中next就相當於插入,而紅黑數可以通過左旋右旋的方式減少查找深度

Hash算法

Hash算法也叫散列算法,就是把任意長度值(Key)通過散列算法變幻成固定長度的key值,通過這個地址進行訪問的數據結構。它通過把關鍵碼值映射到表中的一個位置來訪問記錄,達到加快查找的速度。這個映射函數叫散列函數,存放記錄的數組叫散列表。

put方法圖解

在這裏插入圖片描述
鏈表存儲說明
  以下代碼是hashmap在put數據時摘抄的一部分邏輯

 // 當產生hash碰撞的情況下的一部分處理邏輯
 for (int binCount = 0; ; ++binCount) {
	//遍歷當前桶中的所有節點
    if ((e = p.next) == null) {
    	//如果當前索引對應節點的next爲null的情況,即當前索引對應的鏈表中只保存了一個節點
    	//將當前put的key value 創建新的節點(next 爲null),原來節點的next指向該新節點
        p.next = newNode(hash, key, value, null);
        if (binCount >= TREEIFY_THRESHOLD - 1) 
            treeifyBin(tab, hash);
        break;
    }
    if (e.hash == hash &&
        ((k = e.key) == key || (key != null && key.equals(k))))
        break;
    p = e;
}

HashMap map = new HashMap<>() 的執行過程

jdk8之前:
 構造方法中創建了一個長度是16的Entry[] table 用來存儲鍵值對數據。
jdk8之後:
 不在構造方法中創建,在第一次put方法時創建的 Node[] table 來保存數據。

調用put 時保存數據的過程

 put的數據在數組中的位置是根據 key 調用String類中的重寫之後的hashCode()方法計算出的值,然後結合數組長度結合某種算法計算出對應的index值來確定數組中的位置。
 如果之後put的key計算出的索引和原來的一致,此時會比較兩個hash值是否相等,如果不想等,則在此索引位置對應的空間劃一個節點來保存該數據。如果hash值相等,則發生hash碰撞,這時會調用String中的equals方法比較兩個值得內容是否相等,如果比較的內容相等,則覆蓋原來的,如果不想等,繼續向下和其它的數據key進行比較,如果都不想等,則劃出一個節點存儲數據
總結:
在這裏插入圖片描述

map.put存儲圖解 (圖片來自網絡)

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章