equals() 必須同步覆寫 hashCode(),否則放入 HashSet 等散列容器時會產生重複元素,且不拋異常,極難排查。SortedSet/TreeSet)的元素必須實現 Comparable。在 compareTo() 中切勿使用 return i - j,因整數溢出會導致邏輯錯誤,應寫為 return (i < j ? -1 : (i == j ? 0 : 1))。SortedSet 的語義是「按比較函數排序」,而非「按插入順序」。PriorityQueue 同樣依賴 Comparable 控制元素優先級。| 實現類 | 底層結構 | 核心特點 |
|---|---|---|
HashMap | 散列表(數組+鏈表/紅黑樹) | 查找最快;可調節初始容量與負載因子;非線程安全 |
LinkedHashMap | 散列表+雙向鏈表 | 迭代順序為插入順序或 LRU 訪問順序;適合構建 LRU 緩存 |
TreeMap | 紅黑樹 | 鍵自動按 Comparable 或 Comparator 排序;唯一提供 subMap() 獲取子映射 |
WeakHashMap | 弱引用鍵的散列表 | 鍵無外部強引用時可被 GC 回收;適合緩存場景 |
IdentityHashMap | 散列表 | 用 == 而非 equals() 比較鍵;特殊用途 |
關鍵規則:任何作為 Map 鍵的對象必須正確實現 equals();若用於散列 Map 還需實現 hashCode();若用於 TreeMap 則需實現 Comparable。
Object.hashCode() 默認基於對象地址,分佈不均,極易碰撞。hashCode & (length-1)(長度為 2 的冪次,用位掩碼代替取模,極大提升 get 性能)。Entry<K,V> 鏈表,get 時先定位桶,再線性遍歷 equals() 比對。hashCode() 核心原則:同一對象多次調用必須返回相同值;不應依賴易變字段;不應依賴 this(即默認實現),否則無法通過「等值新鍵」查找舊值。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 代碼的基石。