繁体   English   中英

Java中的equals()和hashCode()协定

[英]equals() and hashCode() contract in Java

Bert Bates和Kathy Sierra的SCJP 6学习指南在第554页中指出(除其他要求外) x.hashCode()!= y.hashCode()要求x.equals(y)== false

但是Javadoc for Object并未明确提及此类要求。 引用:
如果根据equals(Object)方法,两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。

我是否应该将Javadoc所说的作为实质含义,例如eq-> hc 这样,这两个来源之间就不会有冲突。

这两个语句是等效的。

简单地说:

  1. 如果两个哈希码不同,则相等条件下的对象肯定不同。
  2. 如果两个哈希码相同,我们就不知道。 (但在许多实际情况下,对象将相等)。

正如z5h所说,这些语句是等效的。

对于逻辑条件x和y,“ x表示y”与“!y表示!x”相同。

从逻辑上讲,“如果某物是公共汽车,则为红色”等同于“如果某物不是红色,则其不是公共汽车”。

这是对立的

我是否应该将Javadoc所说的作为实质含义,例如eq-> hc。

是的,这正是它的意思:两个对象在equalsequals意味着它们的哈希码必须相等。

这些语句之间没有冲突,它们是等效的。

p: x.equals(y)
q: x.hashCode() == y.hashCode()
p implies q
not q implies not p

关于HashMap的基本事实。
1. HashMap将为每个键生成哈希码,而与对象类型无关。
2.具体来说-将根据键和值(即条目)生成哈希码

实验:假设用户定义的对象(例如SPObject)是哈希映射的键; SPObject中只有一个参数( name )。 请参阅: http//www.programcreek.com/2011/07/java-equals-and-hashcode-contract/

如果没有在SPObject类中正确编写hashCode()和equals(),则会出现以下问题。
放入2个条目-新的SPObject(“ SP”)和新的SPObject(“ SP”)。 这些被视为不同的对象,并成功存储在Map中。

map.get(new SPObject(“ SP”))将返回null。
map.contains(new SPObject(“ SP”))将返回false。

如果没有正确处理hashCode / equals合同,则结果是这样。

hashCode()     |    equals()    | Treated as | Description
No             |      No        | Duplicate  | Stored in different buckets.
                                             | Treated as different object.

Yes            |      No        | Duplicate  | Stored in same bucket.
                                             | Treated as different object. 
                                             | Because, the default(Object) equals method will check only the reference of objects.     

No             |      Yes       | Duplicate  | Stored in different buckets.Treated as different object

Yes(hashlogic) |      Yes       | Unique     | Stored in same bucket.Treated as same object.Efficient.

Yes(constant)  |      Yes       | Unique     | Stored in same bucket.Treated as same object.
                                             | Inefficient, because it will iterate bucket elements for equality check.

hashCode背后的基本思想是,知道某个对象报告的hashCode值与某个其他对象有权获得的哈希值不同的实体会假定这些对象不相等,而无需进一步检查它们。 因为整数支持与等效性有关的各种公理,所以实体可能会知道两个哈希码不同而无需直接比较它们。 例如,知道其中一个报告了一个偶数,而另一个报告了一个奇数,就足以表明它们不匹配。 这样的假设通常使实体能够快速识别出可能无法包含正在查找的对象的大部分集合,从而不必费心检查这些区域。

引用的有关hashCode和equals的“要求”都包含一个未声明的前提:在X.equals(Y)报告为true的情况下,人们不希望实体错误地将其假定为false。 通常,代码根据错误的假设行事是非常糟糕的,因此前提是,我们不希望实体对对象的相等性做出错误的假设是合理的。 《学习指南》引用了以下事实:如果两个对象的哈希码不相等,则假定它们不相等。 做这样的假设符合实际需要,他们不平等的。 JavaDoc本质上暗示着这样一个事实,即如果两个对象相等,并且一个人要避免让实体认为它们不会成为实体并且没有注意到它们是实体,则必须确保一个人返回的hashCode值也将被返回。另一个。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM