何时需要重写等于和哈希编码方法?

2022-09-04 05:55:05

可能的重复:
在Java中覆盖等于和哈希码

如果我有

class A {
    int x = 1;
}
...
A a1 = new A();
A a2 = new A();
a1.equals(a2);

如果我比较A的2个实例而不覆盖等于方法,我会得到预期的结果吗?


答案 1

如果我比较A的2个实例而不覆盖等于方法,我会得到预期的结果吗?

这取决于您对:)

默认实现将为您提供引用相等性 - 换句话说,当您比较两个引用时,仅当它们是对同一对象的引用时,才会返回 true。equals

您通常会重写以实现“值相等” - 其中两个不同的对象被视为相等,通常是由于本身具有相等的字段值。相等的确切含义将取决于您的设计 - 例如,这两个对象仍然可以通过其他方式进行区分。equals

如果覆盖 ,则还应重写以与 一致,以便如果 为 true,则 .这将允许类的实例在基于哈希的集合中用作键(例如),以便您可以基于等于原始键的键查找值,而不必使用对确切的原始键对象的引用。equalshashCodeequalsa.equals(b)a.hashCode() == b.hashCode()HashMap


答案 2

如果我比较A的2个实例而不覆盖等于方法,我会得到预期的结果吗?

哈哈由于您已经显式创建了两个不同的实例。

为什么?equals 的默认实现检查两个相关对象是否指向 java 虚拟内存中的同一内存位置(此默认行为在 java.lang.Object.equals()中定义)

何时需要重写等于和哈希编码方法?

当程序员同时覆盖 equals() 和 hashcode() 时,最常见的情况是,如果您需要将相关类的实例用作

  1. java.util.Map 实现中的键
  2. java.util.Set 实现中的值
  3. 您想检查同一类的两个不同实例之间的值是否相等(在这种情况下,重写 equals() 是必需的,hashcode() 不是 - 但这是一个很好的编程实践)

等价和哈希码的总合约是:

if a1.equals(a2)
    it is mandatory that a1.hashcode() == a2.hashcode()
if a1.hashcode() == a2.hashcode()
    it is not mandatory that a1.equals(a2)

我猜想,足够处理一天的数据:)


推荐