在 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