Java equals和hashCode
我遇到了一个关于equals和hashCode契约的问题: 给你 鉴于:Java equals和hashCode,java,equals,hashcode,scjp,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 } }
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:
D:
我有一个关于最后一个选项D的问题,假设两个对象
代码。长度=10,余额=10,比率=100
代码。长度=10,余额=100,费率=10
然后使用D中的
equals()
方法,我们得到A.equals(B)
求值为true
对吗?但是他们得到了不同的哈希代码,因为他们有不同的余额?是我在什么地方误解了这个概念吗?有人能帮我澄清一下吗?你说得对,因为这一点,D是不合适的
更一般地说,hashCode
和equals
基本上应该以相同的方式考虑相同的字段。当然,这是一个非常奇怪的equals
实现,您通常应该检查所涉及的每个字段之间是否相等。在一些情况下,字段可能以允许乘法等的方式相互关联,但我不希望这涉及字符串长度
一个经常让人困惑的重要问题是,不同的对象拥有相同的哈希代码是有效的;您突出显示的情况(相等的对象具有不同的哈希代码)是不可接受的。您必须至少检查
.hashCode()
使用的所有字段,以便相等的对象具有相同的哈希。但是你可以在equals中检查更多的字段,用相同的散列来检查不同的对象是完全正确的。看起来你在做SCJP1.6?凯瑟琳·塞拉(Katherine Sierra)和伯特·贝茨(Bert Bates)的SCJP 1.6书很好地介绍了这个主题
注意:这就是为什么在从.hashCode()
返回常量值时实现一个有用的.equals()
是合法的,这都是为了履行合同(就这个问题而言)。不同的实现(hasCode和equal)有不同的局限性和它自己的优势,所以开发人员需要检查这一点
但是他们得到不同的哈希代码,因为他们有不同的平衡?确切地但这就是为什么您应该选择选项C。问题是要测试您对实现合同概念的把握,而不是哪种hascode更适合该场景 更多说明:
您需要经常检查的是: 您的
hashCode()
实现应该使用与equals()
方法相同的实例变量。
在这里,这些实例变量是:
code.length()
和bal
在hashCode()中使用,因此您也只能在equals()
中使用这些相同的变量。(除非您可以编辑hashCode()实现并向其添加rate
)通常,如果您在类中重写了另一个,则应该始终重写其中一个。如果不这样做,当该类用于hashmaps/hashtables等时,您可能会发现自己陷入麻烦
请参阅:谢谢您的帮助,我想我明白了。是的,我正在使用这本书为scjp学习,我从考试模拟器中得到了这个问题。你也可以在Josh Bloch的《有效Java第二版》中阅读这个主题。解释得很好!问题不是“我应该重写吗?”,而是关于它们的实现。这回答了一个不同的问题。
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;