首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

《Thinking in Java》容器深度解析:集合與映射的核心機制

     編輯:Java 綜合教學

《Thinking in Java》容器深度解析:集合與映射的核心機制

一、 Set 與排序容器的關鍵契約

  1. 覆寫 equals() 必須同步覆寫 hashCode(),否則放入 HashSet 等散列容器時會產生重複元素,且不拋異常,極難排查。
  2. 用於排序容器(SortedSet/TreeSet)的元素必須實現 Comparable。在 compareTo() 中切勿使用 return i - j,因整數溢出會導致邏輯錯誤,應寫為 return (i < j ? -1 : (i == j ? 0 : 1))。
  3. SortedSet 的語義是「按比較函數排序」,而非「按插入順序」。
  4. PriorityQueue 同樣依賴 Comparable 控制元素優先級。

二、 Map 族譜與核心特性

實現類底層結構核心特點
HashMap散列表(數組+鏈表/紅黑樹)查找最快;可調節初始容量與負載因子;非線程安全
LinkedHashMap散列表+雙向鏈表迭代順序為插入順序或 LRU 訪問順序;適合構建 LRU 緩存
TreeMap紅黑樹鍵自動按 Comparable 或 Comparator 排序;唯一提供 subMap() 獲取子映射
WeakHashMap弱引用鍵的散列表鍵無外部強引用時可被 GC 回收;適合緩存場景
IdentityHashMap散列表用 == 而非 equals() 比較鍵;特殊用途

關鍵規則:任何作為 Map 鍵的對象必須正確實現 equals();若用於散列 Map 還需實現 hashCode();若用於 TreeMap 則需實現 Comparable。

三、 散列機制深度剖析

  1. Object.hashCode() 默認基於對象地址,分佈不均,極易碰撞。
  2. 散列表以數組為核心,索引 = hashCode & (length-1)(長度為 2 的冪次,用位掩碼代替取模,極大提升 get 性能)。
  3. 碰撞通過「鏈表法」解決:桶位存儲 Entry<K,V> 鏈表,get 時先定位桶,再線性遍歷 equals() 比對。
  4. 設計 hashCode() 核心原則:同一對象多次調用必須返回相同值;不應依賴易變字段;不應依賴 this(即默認實現),否則無法通過「等值新鍵」查找舊值。
  5. 優秀的 hashCode() 應「計算快、分佈均、基於不可變內容」。

四、 容器性能與同步控制

  • 棄用 Vector/Hashtable,改用 ArrayList/HashMap + 顯式同步或並發容器。
  • Collections.synchronizedXxx() 可為任意容器添加同步包裝,最佳實踐:List list = Collections.synchronizedList(new ArrayList()); 一行完成,避免洩漏非同步引用。
  • 並發場景首選 ConcurrentHashMap、CopyOnWriteArrayList、CopyOnWriteArraySet,避免 ConcurrentModificationException。

五、 引用類型與弱鍵映射

  • SoftReference(記憶體不足才回收)、WeakReference(GC 掃描即回收)、PhantomReference(僅用於追蹤 GC 時機)提供不同級別的「可達性」。
  • WeakHashMap 內部鍵為 WeakReference,自動清理無外部引用的鍵值對,極適合「鍵值對生命週期與鍵外部引用綁定」的緩存場景。
  • ReferenceQueue 可作為「回收前清理」的通道,PhantomReference 必須配合使用。

六、 遺留容器(僅作了解)

  • Enumeration 為舊版迭代器,功能較弱,優先用 Iterator。
  • BitSet 適合大量「開/關」標誌位存儲,但最小 64 位,小規模場景首選 EnumSet(類型安全、可讀性強)。

掌握容器的底層數據結構、散列原理、equals/hashCode 契約與並發特性,是寫出高性能、無 Bug Java 代碼的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved