这是一个令人满意的合同等于实施吗?

时间:2010-10-19 01:53:41

标签: java

在书中看到这个:

假设:

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合同?

5 个答案:

答案 0 :(得分:4)

假设SortOf Acode = "AA"; bal=2; rate=2SortOf Bcode = "A"; bal=4; rate=2; 然后,对于Acode.length = 2bal = 2rate = 2Bcode.length = 1bal = 4rate=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大型集合。