兩個 `HashMap` 可直接用 `equals()` 比較嗎?答案是**肯定的**,且 JDK 已內建完善的比較邏輯。本文透過源碼深度剖析 `HashMap.equals()` 的實現細節,揭示其「先比大小、再比鍵值、嚴格匹配」的核心演算法,助你理解為何它能精準判斷兩個 Map 是否「內容相等」。
HashMap n1 = new HashMap<>() {{ put("2", "s"); }};
HashMap n2 = new HashMap<>() {{ put("2", "s"); }};
System.out.println(n1.equals(n2)); // 輸出: true
雙括號初始化是匿名內部類寫法 (JDK 1.7+),等同於建立實例後連續 `put`。結果為 `true`,證明 `equals` 比較的是**內容**而非引用。
`HashMap` 未覆寫 `equals`,繼承自 `AbstractMap`,核心邏輯如下:
public boolean equals(Object o) {
if (o == this) return true; // 1. 同引用快速返回
if (!(o instanceof Map)) return false; // 2. 必須是 Map 介面實現
Map<?,?> m = (Map<?,?>) o;
if (m.size() != size()) return false; // 3. 大小不同直接 false
try {
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext()) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
if (value == null) { // 4. 值為 null 特殊處理
if (!(m.get(key) == null && m.containsKey(key))) return false;
} else { // 5. 值非 null 用 equals 比較
if (!value.equals(m.get(key))) return false;
}
}
} catch (ClassCastException | NullPointerException unused) {
return false; // 6. 型別不兼容/空指針保護
}
return true; // 7. 全部匹配,相等
}
`Map.equals()` 實現了**數學意義上的集合相等**:同鍵集、同值映射。其源碼展示了嚴謹的邊界處理 (null 值語義、型別安全、異常防禦),是 Java 集合框架設計精髓的縮影。下次當你寫 `map1.equals(map2)` 時,腦海中應浮現這套「比大小、遍鍵、比值、防 null、捕異常」的標準流程。