博客 / 詳情

返回

HashMap,Java 8 後紅黑樹機制

在HashMap中,當發生哈希衝突且key不同時,追加到鏈表尾部或紅黑樹中的詳細機制如下:

1. 追加到鏈表尾部(Java 8之前)

  • Java 8之前,HashMap使用「頭插法」將新節點插入到鏈表頭部
  • Java 8及以後,改為使用「尾插法」將新節點追加到鏈表尾部
  • 這樣做的主要原因是避免在多線程環境下可能導致的鏈表成環問題,同時配合紅黑樹優化,使查詢性能更穩定

2. 紅黑樹轉換機制

當滿足以下兩個條件時,鏈表會轉換為紅黑樹:

  • 鏈表長度超過閾值(默認為8)
  • 數組長度大於等於64(如果數組長度小於64,會先進行擴容而不是樹化)

3. 紅黑樹插入過程

當需要將新節點插入到紅黑樹時:

  1. 轉換條件檢查:首先檢查是否滿足樹化條件,不滿足則仍使用鏈表
  2. 樹化操作:如果鏈表長度≥8且數組長度≥64,則調用treeifyBin()方法將鏈表轉換為紅黑樹
  3. 紅黑樹插入規則

    • 將鍵值對包裝為TreeNode類型節點
    • 根據key的hashCode和equals方法確定插入位置
    • 按照紅黑樹的插入規則(先作為二叉搜索樹插入,然後進行着色和旋轉以保持紅黑樹性質)
    • 在紅黑樹中,節點按key的哈希值和比較結果排序,當hash值相同時會調用key的compareTo方法(如果實現了Comparable)或使用System.identityHashCode

4. 退化機制

當紅黑樹中的節點數量減少到6個以下時,會自動退化為鏈表,以節省內存空間

5. 性能對比

  • 鏈表查詢時間複雜度:O(n),適用於衝突較少的場景
  • 紅黑樹查詢時間複雜度:O(log n),適用於衝突較多的場景
  • 這種自適應的結構確保了HashMap在不同數據分佈情況下都能保持較好的性能
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.