我什么时候需要覆盖equals和hashcode方法?

时间:2012-10-30 06:53:08

标签: java equals

  

可能重复:
  Overriding equals and hashCode in Java

如果我有

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

如果我比较两个A的实例而没有覆盖equals方法,我会得到预期的结果吗?

3 个答案:

答案 0 :(得分:30)

  

如果我比较两个A的实例而没有覆盖equals方法,我会得到预期的结果吗?

这取决于你的期望:)

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

您通常会覆盖equals以实现“值相等” - 其中两个不同的对象被认为是相等的,通常是由于它们本身具有相等的字段值。平等的确切含义取决于您的设计 - 例如,这两个对象在其他方面仍然可以区分。

如果您覆盖equals,则覆盖hashCode以与equals保持一致,这样如果a.equals(b)为真,那么a.hashCode() == b.hashCode()。这将允许您的类的实例用作基于散列的集合中的键(例如HashMap),以便您可以根据与原始相等的键来查找值一,而不是必须使用对确切原始密钥对象的引用。

答案 1 :(得分:3)

  

如果我比较两个A的实例而没有覆盖equals方法,那么   我得到预期的结果?

没有。由于您已明确创建了两个不同的实例。

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

  

我什么时候需要覆盖equals和hashcode方法?

当程序员覆盖equals()和hashcode()时,最常见的情况是你需要使用相关类的实例

  1. java.util.Map实现中的键
  2. java.util.Set实现中的值
  3. 你想检查同一个类的两个不同实例之间的值的相等性(在这种情况下,覆盖equals()是强制性的,hashcode()不是 - 但是是一个很好的编程实践)
  4. 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)
    

    我想有足够的数据可以处理一天:)

答案 2 :(得分:2)

equals的默认实现测试变量是否引用同一个对象。如果那不是您想要的,那么您需要覆盖equals。覆盖equals时,通常需要覆盖hashcode以使对象可用于哈希表(或使用哈希码的其他数据结构)。