在 Java 開發中,hashCode() 是 Object 類別中定義的核心方法,主要用於雜湊表結構(如 HashMap、HashSet)快速定位物件儲存位置。Java 規範嚴格要求:若兩個物件透過 equals() 比較為相等,則它們的 hashCode() 必須相同;反之,hashCode() 相同的物件不一定 equals() 為真。
1. 一致性:同一物件在執行期間多次呼叫 hashCode() 應回傳相同整數(前提是 equals() 比較所用欄位未變更)。
2. 相等性蕴含:a.equals(b) == true → a.hashCode() == b.hashCode()。
3. 非對稱性:hashCode() 相等不保證 equals() 為真(發生碰撞時)。
public class HashCodeDemo {
public static void main(String[] args) {
String str1 = "aaa";
String str2 = str1; // 同一參考
String str3 = "bbb"; // 不同內容
System.out.println(str1.equals(str2)); // true
System.out.println("str1.hashCode(): " + str1.hashCode()); // 96321
System.out.println("str2.hashCode(): " + str2.hashCode()); // 96321
System.out.println("str3.hashCode(): " + str3.hashCode()); // 97314
}
}
輸出結果:
true
str1.hashCode(): 96321
str2.hashCode(): 96321
str3.hashCode(): 97314
str1 與 str2 指向同一字串物件,equals() 為 true,雜湊碼自然相同。str3 內容不同,雜湊碼也不同(97314 vs 96321)。hashCode(),演算法為 s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1],確保相同內容產生相同雜湊值。覆寫 equals() 時 務必同步覆寫 hashCode(),否則在雜湊容器中會導致「找不到已放入的物件」等詭異 Bug。常用策略:
@Override
public int hashCode() {
return Objects.hash(field1, field2, field3); // JDK 7+ 推薦
}
或手動實作:31 * result + (field == null ? 0 : field.hashCode())。
優良的 hashCode() 應盡量分散,減少碰撞,提升 HashMap 存取效率。若計算成本高,可考慮快取雜湊值(如 String 內部快取)。