在 Java 中重寫 Hashcode 函式
Java 中的 hashcode 是一個使用雜湊演算法並返回一個表示物件的整數值的函式。hashcode() 是 Object 類的一部分,這意味著該函式可用於繼承 Object 類的每個類。
本文將展示我們如何重寫 hashcode() 方法來提供我們的實現。
為什麼我們要重寫 hashcode() 方法
在我們繼續重寫 hashcode() 函式之前,我們應該瞭解為什麼我們需要重寫這個方法。要記住的重要一點是 equals() 和 hashcode() 方法一起使用,並且當 equals() 函式被重寫時,通常強制重寫 hashcode() 方法。這是因為 hashcode() 表示如果物件相等,則它們的雜湊碼也必須相等。
為了實際理解重寫 hashcode() 方法背後的動機,我們建立了一個示例,其中包含兩個名為 HashCodeExample 和 DummyClass 的類。在 DummyClass 中,我們提供了一個設定 abc 變數的簡單建構函式。現在在 HashCodeExample 類中,我們建立 DummyClass 類的兩個例項,並將它們命名為 dummyClass1 和 dummyclass2,在它們的建構函式中具有相同的值。
我們使用 equals() 方法比較兩個例項,但輸出顯示它們不相等。
public class HashCodeExample {
public static void main(String[] args) {
DummyClass dummyClass1 = new DummyClass(10);
DummyClass dummyClass2 = new DummyClass(10);
System.out.println(dummyClass1.equals(dummyClass2));
}
}
class DummyClass {
int abc;
public DummyClass(int abc) {
this.abc = abc;
}
}
輸出:
false
這是因為 Java 中的每個物件例項都有一個唯一的雜湊碼,我們可以通過在兩個物件上呼叫 hashCode() 方法來檢查它。輸出顯示兩個物件的整數值不同。
System.out.println(dummyClass1.hashCode());
System.out.println(dummyClass2.hashCode());
輸出:
2065951873
1791741888
為了解決不相等物件的問題,我們可以重寫 equals() 函式並使用我們的實現。下面的程式碼與第一個程式相同,但我們重寫了將 Object 作為引數並返回 boolean 的 equals() 方法。
在 equals() 函式中,我們將 Object 型別的引數 o 轉換為 DummyClass 的型別,它返回 DummyClass 的例項。現在我們將 DummyClass 類的變數 abc 與作為引數傳入方法的物件變數 abc 進行比較。
輸出顯示 dummyClass1.equals(dummyClass2) 的結果為 true,因為我們修改了預設實現以在例項的值相同時返回 true。
public class HashCodeExample {
public static void main(String[] args) {
DummyClass dummyClass1 = new DummyClass(10);
DummyClass dummyClass2 = new DummyClass(10);
System.out.println(dummyClass1.equals(dummyClass2));
}
}
class DummyClass {
int abc;
public DummyClass(int abc) {
this.abc = abc;
}
@Override
public boolean equals(Object o) {
DummyClass dummyClassObj = (DummyClass) o;
return this.abc == dummyClassObj.abc;
}
}
輸出:
true
上述解決方案僅在我們比較值而不是雜湊碼時才有效,因為物件 dummyClass1 和 dummyClass2 的雜湊碼仍然不同。
為了更好地說明這一點,我們建立了一個 HashSet(),它返回一個 Set<DummyClass> 型別的物件,並使用 add() 函式將兩個 DummyClass 物件新增到其中。現在我們列印 Set 並在輸出中得到兩個具有不同引用的物件,這證明 DummyClass 物件具有不同的雜湊碼。
這是我們重寫 hashcode() 函式以解決問題的地方,我們將在下面的下一個示例中看到。
import java.util.HashSet;
import java.util.Set;
public class HashCodeExample {
public static void main(String[] args) {
DummyClass dummyClass1 = new DummyClass(10);
DummyClass dummyClass2 = new DummyClass(10);
Set<DummyClass> dummyClassSet = new HashSet<>();
dummyClassSet.add(dummyClass1);
dummyClassSet.add(dummyClass2);
System.out.println(dummyClassSet);
}
}
class DummyClass {
int abc;
public DummyClass(int abc) {
this.abc = abc;
}
@Override
public boolean equals(Object o) {
DummyClass dummyClass = (DummyClass) o;
return this.abc == dummyClass.abc;
}
}
輸出:
[DummyClass@7b23ec81, DummyClass@6acbcfc0]
重寫 Java 中的 hashcode() 方法
為了在 hashcode() 方法中使用我們的實現,我們首先重寫 DummyClass 類中的 hashcode() 方法並返回類變數 abc 的值。現在雜湊碼被替換為 abc 的值。現在,如果我們列印 dummyClassSet,我們只會得到一個物件,因為雜湊碼或引用是相同的。
import java.util.HashSet;
import java.util.Set;
public class HashCodeExample {
public static void main(String[] args) {
DummyClass dummyClass1 = new DummyClass(10);
DummyClass dummyClass2 = new DummyClass(10);
Set<DummyClass> dummyClassSet = new HashSet<>();
dummyClassSet.add(dummyClass1);
dummyClassSet.add(dummyClass2);
System.out.println(dummyClassSet);
}
}
class DummyClass {
int abc;
public DummyClass(int abc) {
this.abc = abc;
}
@Override
public boolean equals(Object o) {
DummyClass dummyClass = (DummyClass) o;
return this.abc == dummyClass.abc;
}
@Override
public int hashCode() {
return abc;
}
}
輸出:
[DummyClass@a]
如果我們列印物件 dummyClass1 和 dummyClass2 的雜湊碼,我們會得到相同的雜湊碼。
System.out.println(dummyClass1.hashCode());
System.out.println(dummyClass2.hashCode());
輸出:
10
10
Rupam Saini is an android developer, who also works sometimes as a web developer., He likes to read books and write about various things.
LinkedIn