equals和hashCode

时间:2010-08-05 05:56:31

标签: java equals hashcode scjp

我遇到了关于equals和hashCode合同的问题: 这是

鉴于:

class SortOf { 
  String name; 
  int bal; 
  String code; 
  short rate; 
  public int hashCode() { 
    return (code.length() * bal); 
  } 
  public boolean equals(Object o) { 
    // insert code here 
  } 
} 

以下哪项将满足equals()和hashCode()的合同 类? (选择所有适用的选项。)

正确答案     C:

return ((SortOf)o).code.length() * ((SortOf)o).bal  ==  this.code.length() * 
    this.bal; 

D:

return ((SortOf)o).code.length() * ((SortOf)o).bal * ((SortOf)o).rate ==
    this.code.length() * this.bal * this.rate; 

我对最后一个选项D有疑问,比如两个对象

A:code.length = 10,bal = 10,rate = 100

B:code.length = 10,bal = 100,rate = 10

然后在D中使用equals()方法,我们会A.equals(B)评估为true吗?但是他们得到了一个不同的hashCode,因为他们有不同的余额?难道我在某个地方误解了这个概念吗?有人可以为我澄清一下吗?

5 个答案:

答案 0 :(得分:4)

你是对的 - 由于这个原因,D不合适。

更一般地说,hashCodeequals基本上应该以相同的方式考虑相同的字段。当然,这是一个非常奇怪的equals实现 - 您通常应检查所涉及的每个字段之间的相等性。在少数情况下,字段可能以允许乘法等的方式相互关联,但我不希望这涉及字符串长度......

经常让人感到困惑的一个重要问题是, 对于不等对象具有相同的哈希码是有效的;你突出显示的情况(具有不同哈希码的相等对象)是不可接受的。

答案 1 :(得分:0)

您必须至少检查.hashCode()使用的所有字段,以便相同的对象具有相同的哈希值。但是你可以检查equals中的更多字段,它可以完全没有具有相同散列的不同对象。看来你在做SCJP 1.6吗?这个主题在Katherine Sierra和Bert Bates的SCJP 1.6书中得到了很好的阐述。

注意:这就是为什么从.equals()

返回常量值时实现有用.hashCode()的合法性

答案 2 :(得分:0)

所有关于履行合同(就这个问题而言)。不同的实现(hasCode和相等)具有不同的限制和它自己的优点 - 因此它可供开发人员检查。

然后他们得到不同的hashCode,因为他们有不同的余额?
究竟!但这就是为什么你应该选择选项C.这个问题想要测试你对履行契约概念的把握,而不是哪种代码对于场景更好。

更多澄清:
你需要检查的事情是: 您的hashCode()实施应使用equals()方法中使用的相同实例变量。

这些实例变量是:hashCode()中使用的code.length()bal,因此您只能在equals()中使用这些相同的变量。 (除非您可以编辑hashCode()实现并向其添加rate

答案 3 :(得分:0)

  1. hashCode()方法用于获取给定对象的唯一整数。当该对象需要存储在某些HashTable(如HashMap数据结构)中时,此整数用于确定存储桶位置。但是默认情况下,Object的hashCode()方法返回一个整数来表示存储对象的内存地址。

  2. equals()方法,顾名思义,用于简单地验证两个对象的相等性。默认实现只需检查两个对象的对象引用即可验证它们的相等性。

  3. 等于对象必须具有相同的哈希码。

    equals()必须定义一个等式关系。如果未修改对象,则必须保持返回相同的值。 o.equals(null)必须始终返回false。

    hashCode()也必须是一致的,如果对象没有按照equals()进行修改,它必须保持返回相同的值。

    两种方法之间的关系是:

    每当a.equals(b)然后a.hashCode()必须与b.hashCode()相同。

    请参阅:https://howtodoinjava.com/interview-questions/core-java-interview-questions-series-part-1/

答案 4 :(得分:-1)

通常,如果在类中覆盖另一个,则应始终覆盖一个。如果不这样做,当在hashmaps / hashtables等中使用该类时,您可能会遇到麻烦。