简体   繁体   English

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

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

The SCJP 6 Study Guide from Bert Bates and Kathy Sierra states on page 554 (among other requirements) that x.hashCode() != y.hashCode() requires that x.equals(y) == false . Bert Bates和Kathy Sierra的SCJP 6学习指南在第554页中指出(除其他要求外) x.hashCode()!= y.hashCode()要求x.equals(y)== false

But the Javadoc for Object doesn't mention such requirement explicitly. 但是Javadoc for Object并未明确提及此类要求。 Quote: 引用:
If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. 如果根据equals(Object)方法,两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。

Should I take what Javadoc says as a material implication, such as eq -> hc ? 我是否应该将Javadoc所说的作为实质含义,例如eq-> hc Then there would be no conflict between these two sources. 这样,这两个来源之间就不会有冲突。

The two statements are equivalent. 这两个语句是等效的。

Put simply: 简单地说:

  1. if two hashcodes differ, the objects are definitely different under equals. 如果两个哈希码不同,则相等条件下的对象肯定不同。
  2. if two hashcodes are the same, we don't know. 如果两个哈希码相同,我们就不知道。 (but in many practical cases the objects will be equal). (但在许多实际情况下,对象将相等)。

As z5h says, the statements are equivalent. 正如z5h所说,这些语句是等效的。

For logical conditions x and y, "x implies y" is the same as "!y implies !x". 对于逻辑条件x和y,“ x表示y”与“!y表示!x”相同。

"If something is a bus, it's red" is logically equivalent to "if something isn't red, it's not a bus." 从逻辑上讲,“如果某物是公共汽车,则为红色”等同于“如果某物不是红色,则其不是公共汽车”。

This is contraposition . 这是对立的

Should I take what Javadoc says as a material implication, such as eq -> hc. 我是否应该将Javadoc所说的作为实质含义,例如eq-> hc。

Yes, that's exactly what it's saying: two objects being equal under equals implies their hashcodes must be equal. 是的,这正是它的意思:两个对象在equalsequals意味着它们的哈希码必须相等。

There is no conflict between these statements, they are equivalent. 这些语句之间没有冲突,它们是等效的。

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

Basic Facts about HashMap. 关于HashMap的基本事实。
1. HashMap will generate hashcode for each key irrespective of the object type. 1. HashMap将为每个键生成哈希码,而与对象类型无关。
2. To be specific - hashcode will be generated based on the key and value(ie entry) 2.具体来说-将根据键和值(即条目)生成哈希码

Experiment: Consider a user-defined object(eg. SPObject) is the key for a hashmap; 实验:假设用户定义的对象(例如SPObject)是哈希映射的键; SPObject has only one parameter ( name ) in it. SPObject中只有一个参数( name )。 Refer: http://www.programcreek.com/2011/07/java-equals-and-hashcode-contract/ 请参阅: http//www.programcreek.com/2011/07/java-equals-and-hashcode-contract/

If hashCode() and equals() are not written properly in the SPObject class, the issues are below. 如果没有在SPObject类中正确编写hashCode()和equals(),则会出现以下问题。
Put 2 entries - new SPObject("SP") & new SPObject("SP"). 放入2个条目-新的SPObject(“ SP”)和新的SPObject(“ SP”)。 These are treated as different object and gets stored in Map successfully. 这些被视为不同的对象,并成功存储在Map中。

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

This is the result, if the hashCode/equals contract is not handled properly. 如果没有正确处理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.

The fundamental idea behind hashCode is that an entity which knows that an object has reported a hashCode value different from what some other object is entitled to assume that the objects are unequal without having to examine them any further. hashCode背后的基本思想是,知道某个对象报告的hashCode值与某个其他对象有权获得的哈希值不同的实体会假定这些对象不相等,而无需进一步检查它们。 Because the integers uphold various axioms related to equivalence, an entity may know that two hash codes differ without directly comparing them. 因为整数支持与等效性有关的各种公理,所以实体可能会知道两个哈希码不同而无需直接比较它们。 For example, knowledge that one of them has reported an even number and the other an odd number would suffice to show that they can't match. 例如,知道其中一个报告了一个偶数,而另一个报告了一个奇数,就足以表明它们不匹配。 Such assumptions often allow entities to quickly identify large portions of collections which cannot possibly contain an object being looked up, and thus not bother examining those areas. 这样的假设通常使实体能够快速识别出可能无法包含正在查找的对象的大部分集合,从而不必费心检查这些区域。

Both of the cited "requirements" about hashCode and equals include an unstated premise: In cases where X.equals(Y) reports true, one won't want entities to incorrectly assume it to be false. 引用的有关hashCode和equals的“要求”都包含一个未声明的前提:在X.equals(Y)报告为true的情况下,人们不希望实体错误地将其假定为false。 In general, it's very bad for code to act upon false assumptions, so the premise that one wouldn't want entities to make incorrect assumptions about the equality of objects is reasonable. 通常,代码根据错误的假设行事是非常糟糕的,因此前提是,我们不希望实体对对象的相等性做出错误的假设是合理的。 The Study Guide quote alludes to the fact that if two objects have unequal hashcodes, they'll be presumed unequal; 《学习指南》引用了以下事实:如果两个对象的哈希码不相等,则假定它们不相等。 making such presumption match reality requires that they be unequal. 做这样的假设符合实际需要,他们不平等的。 The JavaDoc essentially alludes to the fact that if two objects are equal, and one wants to avoid having entities assume they won't be and fail to notice that they are, one must ensure that a hashCode value returned by one will also be returned by the other. JavaDoc本质上暗示着这样一个事实,即如果两个对象相等,并且一个人要避免让实体认为它们不会成为实体并且没有注意到它们是实体,则必须确保一个人返回的hashCode值也将被返回。另一个。

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

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