为什么我们要重写 hashcode() 方法
重写 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
这是我们重写 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
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
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
Enjoying our tutorials? Subscribe to DelftStack on YouTube to support us in creating more high-quality video guides. Subscribe