我什么时候需要覆盖equals和hashcode方法?
可能重复:
在Java中覆盖equals和hashCode
如果我有
class A { int x = 1; } ... A a1 = new A(); A a2 = new A(); a1.equals(a2);
如果我比较2个A的实例而没有覆盖equals方法,我会得到预期的结果吗?
如果我比较2个A的实例而没有覆盖equals方法,我会得到预期的结果吗?
这取决于你的期望:)
默认实现将为您提供引用相等性 – 换句话说,当您比较两个引用时, equals
仅在它们引用同一对象时才返回true。
您通常会覆盖equals
以实现“值相等” – 其中两个不同的对象被认为是相等的,通常是由于它们本身具有相等的字段值。 平等的确切含义取决于您的设计 – 例如,两个对象在其他方面仍然可以区分。
如果重写equals
,则还应覆盖hashCode
以使其与equals
一致,这样如果a.equals(b)
为true,则a.hashCode() == b.hashCode()
。 这将允许您的类的实例在基于哈希的集合(例如HashMap
)中用作键,以便您可以基于与原始键相同的键来查找值,而不必使用对该键的引用。确切的原始关键对象。
如果我比较2个A的实例而没有覆盖equals方法,我会得到预期的结果吗?
不会。因为您已明确创建了两个不同的实例。
为什么? equals的默认实现检查两个相关对象是否指向java虚拟内存中的相同内存位置(并且此默认行为在java.lang.Object.equals()中定义)
我什么时候需要覆盖equals和hashcode方法?
当程序员重写equals()和hashcode()时最常见的情况是你需要使用相关类的实例作为
- java.util.Map实现中的键
- java.util.Set实现中的值
- 您想要检查同一个类的两个不同实例之间的值的相等性(在这种情况下,重写equals()是必需的,hashcode()不是 – 但是是一个很好的编程实践)
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)
我想有足够的数据来处理一天:)
equals
的默认实现测试变量是否引用相同的对象。 如果这不是你想要的,那么你需要覆盖equals
。 当您重写equals
,通常需要覆盖哈希表的哈希码,以便在哈希表(或使用哈希码的其他数据结构)中使用。