或者"为什么Sun/Oracle人员每次都强迫我们覆盖equals()和hashCode()?"
每个人都知道,如果你覆盖一个对象的equals()或hashCode(),你也必须覆盖另一个,因为这两者之间有一个契约:
请注意,每当重写此方法[ie equals()]时,通常需要覆盖hashCode方法,以便维护hashCode方法的常规协定,该方法声明相等对象必须具有相等的哈希代码.- Object.equals()的API文档
为什么不在Object类中实现这种方式:
public boolean equals(Object obj) {
return this.hashCode() == obj.hashCode()
}
Run Code Online (Sandbox Code Playgroud)
如果他们这样做,它将使世界其他地方免于必须实施这两种方法.仅覆盖hashCode()就足够了.
我猜这些家伙有充分的理由不这样做.我只是看不到它 - 请为我清楚这一点.
Joa*_*uer 12
如果a.equals(b)返回true则a.hashCode() == b.hashCode()必须求值true.
相反的情况并非如此!有两个对象a.hashCode() == b.hashCode()是真的a.equals(b)是完全有效,但是是假的.
事实上,这是必要的.有2 32个可能的返回值hashCode().在任何给定的时刻,JVM可以容纳超过 2 32个对象(假设有足够的内存,这些天很可能).假设所有对象都不是彼此相等(容易的事,只是让他们可以"s1","s2"......),那么你势必要有校验和冲突(见Pidgeonhole原则).
事实上,这可能是最简单hashCode的实现,是正确的(但在其他方面差得要命)为每类*:
public int hashCode() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它神奇地满足了总hashCode()合同的所有要求.
*除了那些具有hashCode必须实现的已定义和记录的算法的类之外,最好的例子是String.hashCode().