1

我遇到了一个关于 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; 

丁:

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

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

4

5 回答 5

4

你是对的 - 因为这个,D 是不合适的。

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

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

于 2010-08-05T06:01:33.150 回答
0

您必须至少检查所有.hashCode()相等的对象使用的字段是否具有相同的哈希值。但是你可以在equals中检查更多的字段,拥有相同哈希的不同对象是完全可以的。看来你在做 SCJP 1.6?Katherine Sierra 和 Bert Bates 的 SCJP 1.6 书中很好地介绍了这个主题。

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

于 2010-08-05T06:09:15.853 回答
0

一切都是为了履行合同(就这个问题而言)。不同的实现(hasCode 和 equal)有不同的限制和自己的优势 - 所以它供开发人员检查。

但是然后他们得到不同的hashCode,因为他们有不同的平衡?
确切地!但这就是为什么你应该选择选项 C。这个问题想测试你对履行合同概念的把握,而不是哪个 hascode 更适合这个场景。

更多说明:
您需要始终检查的是: 您的hashCode()实现应该使用与方法中使用的相同的实例变量equals()

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

于 2014-02-27T05:31:08.893 回答
0
  1. hashCode() 方法用于获取给定对象的唯一整数。这个整数用于确定桶的位置,当这个对象需要存储在一些像HashMap这样的HashTable数据结构中时。但默认情况下,Object 的 hashCode() 方法返回一个整数来表示存储对象的内存地址。

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

相等的对象必须具有相等的哈希码。

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/

于 2018-03-13T08:27:21.457 回答
-1

一般来说,如果你在一个类中覆盖另一个,你应该总是覆盖一个。如果你不这样做,你可能会发现当该类用于哈希映射/哈希表等时会遇到麻烦。

于 2014-07-18T08:46:05.300 回答