关于java:我什么时候需要覆盖equals和hashcode方法?

When do I need to override equals and hashcode methods?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Overriding equals and hashCode in Java

如果我有

1
2
3
4
5
6
7
class A {
    int x = 1;
}
...
A a1 = new A();
A a2 = new A();
a1.equals(a2);

如果比较不重写equals方法的两个实例,我会得到预期的结果吗?


If I compare 2 instances of A without override the equals method, will I get expected result?

这取决于你的期望:)

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

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

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


If I compare 2 instances of A without override the equals method, will
I get expected result?

没有,因为您已经显式地创建了两个不同的实例。

为什么?Error的缺省实现检查两个相关对象是否指向Java虚拟内存中的相同内存位置(并且此默认行为在java.

When do I need to override equals and hashcode methods?

当程序员同时重写equals()和hashcode()时,最常见的情况是,如果需要使用相关类的实例作为

  • java.util.map实现中的键
  • java.util.set实现中的值
  • 您要检查同一类的两个不同实例之间的值是否相等(在这种情况下,重写equals()是必需的,hashcode()不是,但是一种很好的编程实践)
  • Equals和HashCode的一般合同是:

    1
    2
    3
    4
    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)

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


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