在 Java 中重寫 Hashcode 函式

Rupam Yadav 2023年1月30日 2022年5月1日
  1. 為什麼我們要重寫 hashcode() 方法
  2. 重寫 Java 中的 hashcode() 方法
在 Java 中重寫 Hashcode 函式

Java 中的 hashcode 是一個使用雜湊演算法並返回一個表示物件的整數值的函式。hashcode()Object 類的一部分,這意味著該函式可用於繼承 Object 類的每個類。

本文將展示我們如何重寫 hashcode() 方法來提供我們的實現。

為什麼我們要重寫 hashcode() 方法

在我們繼續重寫 hashcode() 函式之前,我們應該瞭解為什麼我們需要重寫這個方法。要記住的重要一點是 equals()hashcode() 方法一起使用,並且當 equals() 函式被重寫時,通常強制重寫 hashcode() 方法。這是因為 hashcode() 表示如果物件相等,則它們的雜湊碼也必須相等。

為了實際理解重寫 hashcode() 方法背後的動機,我們建立了一個示例,其中包含兩個名為 HashCodeExampleDummyClass 的類。在 DummyClass 中,我們提供了一個設定 abc 變數的簡單建構函式。現在在 HashCodeExample 類中,我們建立 DummyClass 類的兩個例項,並將它們命名為 dummyClass1dummyclass2,在它們的建構函式中具有相同的值。

我們使用 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 作為引數並返回 booleanequals() 方法。

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

上述解決方案僅在我們比較值而不是雜湊碼時才有效,因為物件 dummyClass1dummyClass2 的雜湊碼仍然不同。

為了更好地說明這一點,我們建立了一個 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]

如果我們列印物件 dummyClass1dummyClass2 的雜湊碼,我們會得到相同的雜湊碼。

System.out.println(dummyClass1.hashCode());
System.out.println(dummyClass2.hashCode());

輸出:

10
10
Author: Rupam Yadav
Rupam Yadav avatar Rupam Yadav avatar

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