在书中看到这个:
假设:
class SortOf {
String name;
int bal;
String code;
short rate;
public int hashCode() {
return (code.length() * bal);
}
}
执行以下操作:
public boolean equals(Object o) {
return ((SortOf)o).code.length() * ((SortOf)o).bal * ((SortOf)o).rate == this.code.length() * this.bal * this.rate;
}
满足equals
合同?
答案 0 :(得分:4)
假设SortOf A
有code = "AA"; bal=2; rate=2
且SortOf B
有code = "A"; bal=4; rate=2;
然后,对于A
,code.length = 2
,bal = 2
,rate = 2
和B
有code.length = 1
,bal = 4
,rate=2
。然后A.equals(B)
,但A.hashCode() != B.hashCode()
除了您对代码的其他问题外,我认为这违反了合同。
已编辑添加:实际上,equals()
的此定义可能在技术上满足Object.equals()
的合同,这与hashCode()
的一致性没有要求}。这是Object.hashCode()
的合同,其合同要求与equals()
保持一致。什么是关于小思想和愚蠢的一致性......? < andersoj离开申请法学院>
这equals()
是反身的,对称的,传递的,一致的。我猜这违反了合同,因为.equals(null)
会抛出异常,而不是根据需要返回false
。关于equals()
的所有hashCode()
规范都是:
请注意,通常需要 无论何时覆盖
hashCode
方法 这个方法被覆盖,以便 保持一般合同hashCode
方法,其中指出了这一点 等于对象必须具有相等的哈希值 码。
答案 1 :(得分:3)
否强>
对于初学者,如果ClassCastException
不是false
,您将在运行时获得o
(而不是仅返回SortOf
)。
还有一般合同(见下面的链接):
使用用于计算equals()的同一组字段来计算hashCode()。
您问题中的方法不会这样做。
关于此主题的优秀问答: What issues should be considered when overriding equals and hashCode in Java?
答案 2 :(得分:3)
Joshua Bloch告诉你precisely如何编写并测试 equals和hashCode以使它们符合合同。
更好的是,获得一个可以完美地为您生成的IDE。 IntelliJ在这个以及许多其他方面做得非常出色。
答案 3 :(得分:1)
没有
如果对象相同,则它们必须具有相同的哈希码。
然而
100 * 10 * 10 = 200 * 10 * 5 (equals)
但是
100 * 10 != 200 * 10 (hashCode)
一般来说,我认为你的另一种方式是开发:你有一个自然的想法是什么应该使对象相等(你的东西似乎不适合),然后考虑如何使哈希代码匹配
答案 4 :(得分:1)
其他人都提出“不”,但只是添加,作为一般规则,许多IDE环境(IE Eclipse)提供equals()/ hashCode()实现生成。一般来说,你会想要这样做。但是,如果你正在使用像Hibernate这样的东西,那么非常重要的是不要以一种方式构造它并调用lazy-init'd大型集合。