我遇到了关于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,因为他们有不同的余额?难道我在某个地方误解了这个概念吗?有人可以为我澄清一下吗?
答案 0 :(得分:4)
你是对的 - 由于这个原因,D不合适。
更一般地说,hashCode
和equals
基本上应该以相同的方式考虑相同的字段。当然,这是一个非常奇怪的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)
hashCode()方法用于获取给定对象的唯一整数。当该对象需要存储在某些HashTable(如HashMap数据结构)中时,此整数用于确定存储桶位置。但是默认情况下,Object的hashCode()方法返回一个整数来表示存储对象的内存地址。
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/
答案 4 :(得分:-1)
通常,如果在类中覆盖另一个,则应始终覆盖一个。如果不这样做,当在hashmaps / hashtables等中使用该类时,您可能会遇到麻烦。