HashMap 實作 Map<K,V>,存儲「鍵值對」;HashSet 實作 Set<E>,存儲「唯一元素」。底層 HashSet 直接包裝 HashMap(private transient HashMap<E,Object> map),以元素為 Key,固定虛擬值 PRESENT 為 Value。
| 維度 | HashMap | HashSet |
|---|---|---|
| 介面 | Map | Set |
| 存儲結構 | Key-Value 鍵值對 | 單一元素 |
| 新增方法 | put(K key, V value) | add(E e) |
| 重複判斷 | Key 唯一(hashCode() + equals()) | 元素唯一(同理) |
| Null 支援 | 1 個 null Key,多個 null Value | 1 個 null 元素 |
| 查詢效能 | O(1) 直接定位 Key | O(1) 但需轉換為 Map 查詢 |
| 遍歷方式 | entrySet()、keySet()、values() | iterator()、增強 for |
public boolean add(E e) {
return map.put(e, PRESENT) == null; // put 返回舊值,null 表示新增成功
}
因此 HashSet 去重完全依賴元素正確覆寫 hashCode() 與 equals()。若未覆寫,預設 Object 實作比較記憶體地址,導致「內容相同但物件不同」被視為不同元素。
hashCode() 與 equals() 保持一致性契約PRESENT 虛擬值設計hashCode() 碰撞時,HashMap 鏈表/紅黑樹如何配合 equals() 精確定位HashSet.add() vs ArrayList.contains() 時間複雜度:O(1) vs O(n)HashMap 與 HashSet 雖同屬集合框架、同基於雜湊表,但定位截然不同:前者解決「映射」,後者解決「去重」。理解兩者底層關聯與契約,是寫出高效、正確 Java 代碼的基石。