Map 是鍵值對集合,通過 Key 索引 Value。Java 提供多種實現,最常用的是 HashMap(哈希表)與 TreeMap(紅黑樹)。
HashMap 繼承 AbstractMap,實現 Map 接口。TreeMap 繼承 AbstractMap,實現 NavigableMap(繼承 SortedMap)。| 特性 | HashMap | TreeMap |
|---|---|---|
| 底層數據結構 | 哈希表(數組+鏈表/紅黑樹) | 紅黑樹(自平衡二叉搜索樹) |
| 元素順序 | 無序,不保證迭代順序 | 按 Key 自然順序或 Comparator 排序 |
| Key 要求 | 正確重寫 hashCode() 與 equals() | Key 需實現 Comparable 或提供 Comparator |
| 線程安全 | 非線程安全 | 非線程安全 |
| 性能特點 | 增刪查 O(1) 平均 | 增刪查 O(log n),適合有序遍歷 |
| 調優參數 | 初始容量、負載因子 | 無(樹自平衡) |
| Null Key 支持 | 允許一個 null key | 不允許 null key(比較會拋 NPE) |
HashMap()HashMap(Map<? extends K, ? extends V> m)HashMap(int initialCapacity)HashMap(int initialCapacity, float loadFactor)TreeMap()TreeMap(Map<? extends K, ? extends V> m)TreeMap(Comparator<? super K> comparator)TreeMap(SortedMap<K, ? extends V> m)Map<String, String> hashMap = new HashMap<>();
hashMap.put("a", "aaa"); hashMap.put("b", "bbb"); hashMap.put("c", "ccc"); hashMap.put("d", "ddd");
// 輸出順序不固定,例:ddd, bbb, ccc, aaa
TreeMap<String, String> treeMap = new TreeMap<>();
treeMap.put("a", "aaa"); treeMap.put("b", "bbb"); treeMap.put("c", "ccc"); treeMap.put("d", "cdc");
// 輸出嚴格按 Key 排序:aaa, bbb, ccc, cdc
HashMap 通過 hashCode() 確定桶位置,再用 equals() 精確匹配。若 Key 未正確重寫這兩個方法,會導致「明明 put 了卻 get 不到」的問題。
class Element { int number; Element(int n) { number = n; } }
// 未重寫 hashCode/equals,預設使用 Object 內存地址
Map<Element, Figureout> map = new HashMap<>();
map.put(new Element(5), new Figureout());
Element test = new Element(5);
map.containsKey(test); // false!因為兩個 Element 實例 hashCode 不同
class Element {
int number;
Element(int n) { number = n; }
@Override public int hashCode() { return number; }
@Override public boolean equals(Object o) {
return o instanceof Element && number == ((Element)o).number;
}
}
equals 為 true 時 hashCode 相等。HashMap,性能更優。subMap、headMap、tailMap)時選 TreeMap。ConcurrentHashMap 或 Collections.synchronizedMap。