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() != . hashcode()要求x.equals(y) == false。
But the Javadoc for Object doesn't mention such requirement explicitly. 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.
但是对象的Javadoc没有明确地提到这些要求。引用:如果两个对象根据equals(Object)方法相等,那么在两个对象上调用hashCode方法必须产生相同的整数结果。
Should I take what Javadoc says as a material implication, such as eq -> hc? Then there would be no conflict between these two sources.
我是否应该把Javadoc作为一个重要的含义,比如eq -> hc?那么这两个来源之间就不会有冲突了。
5 个解决方案
#1
13
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.
是的,这就是它的意思:两个对象在同等条件下相等,意味着它们的hashcode必须相等。
#2
12
The two statements are equivalent.
这两个表述是等价的。
Put simply:
简单地说:
- if two hashcodes differ, the objects are definitely different under equals.
- 如果两个hashcode不同,对象在equals下肯定是不同的。
- if two hashcodes are the same, we don't know. (but in many practical cases the objects will be equal).
- 如果两个hashcode是相同的,我们不知道。(但在许多实际情况下,物体是相等的)。
#3
5
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
#4
2
Basic Facts about HashMap.
1. HashMap will generate hashcode for each key irrespective of the object type.
2. To be specific - hashcode will be generated based on the key and value(i.e. entry)
基本事实是HashMap。1。HashMap将为每个键生成hashcode,而不考虑对象类型。2。特定的- hashcode将基于键和值生成(即:条目)
Experiment: Consider a user-defined object(eg. SPObject) is the key for a hashmap; SPObject has only one parameter (name) in it. Refer: http://www.programcreek.com/2011/07/java-equals-and-hashcode-contract/
实验:考虑一个用户定义的对象(如。(SPObject)是hashmap的关键;SPObject只有一个参数(name)。参见: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.
Put 2 entries - new SPObject("SP") & new SPObject("SP"). These are treated as different object and gets stored in Map successfully.
map.get(new SPObject("SP")) will return null.
map.contains(new SPObject("SP")) will return false.
This is the result, if the hashCode/equals contract is not handled properly.
如果hashCode()和equals()没有在SPObject类中正确地编写,问题就在下面。输入两个条目-新的SPObject(“SP”)和新的SPObject(“SP”)。它们被视为不同的对象,并成功地存储在Map中。地图。获取(新的SPObject(“SP”))将返回null。地图。包含(新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.
#5
0
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. 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.
hashCode背后的基本思想是一个实体,它知道一个对象已经报告了一个hashCode值,它与其他对象有权利假定对象是不相等的,而不需要进一步检查它们。因为整数支持与等价相关的各种公理,一个实体可能知道两个哈希码在没有直接比较的情况下是不同的。例如,知道其中一个已经报告了偶数,而另一个奇数则表示它们不能匹配。这样的假设通常允许实体快速识别大量的集合,这些集合不可能包含被查找的对象,因此不需要检查这些区域。
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. 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.
对于hashCode和equals的引用“需求”都包含一个未声明的前提:在X.equals(Y)报告为真的情况下,一个人不希望实体错误地认为它是假的。一般来说,对代码进行错误的假设是非常糟糕的,因此,一个人不希望实体对对象的平等做出错误假设的前提是合理的。研究指南引用了这样一个事实:如果两个对象的hashcode不相等,那么它们将被假定为不相等的;要使这种假设与现实相符,就需要它们是不平等的。JavaDoc实际上暗示了这样一个事实:如果两个对象是相等的,并且一个想要避免实体假设它们不会,并且没有注意到它们是,那么就必须确保一个返回的hashCode值也会被另一个返回。
#1
13
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.
是的,这就是它的意思:两个对象在同等条件下相等,意味着它们的hashcode必须相等。
#2
12
The two statements are equivalent.
这两个表述是等价的。
Put simply:
简单地说:
- if two hashcodes differ, the objects are definitely different under equals.
- 如果两个hashcode不同,对象在equals下肯定是不同的。
- if two hashcodes are the same, we don't know. (but in many practical cases the objects will be equal).
- 如果两个hashcode是相同的,我们不知道。(但在许多实际情况下,物体是相等的)。
#3
5
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
#4
2
Basic Facts about HashMap.
1. HashMap will generate hashcode for each key irrespective of the object type.
2. To be specific - hashcode will be generated based on the key and value(i.e. entry)
基本事实是HashMap。1。HashMap将为每个键生成hashcode,而不考虑对象类型。2。特定的- hashcode将基于键和值生成(即:条目)
Experiment: Consider a user-defined object(eg. SPObject) is the key for a hashmap; SPObject has only one parameter (name) in it. Refer: http://www.programcreek.com/2011/07/java-equals-and-hashcode-contract/
实验:考虑一个用户定义的对象(如。(SPObject)是hashmap的关键;SPObject只有一个参数(name)。参见: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.
Put 2 entries - new SPObject("SP") & new SPObject("SP"). These are treated as different object and gets stored in Map successfully.
map.get(new SPObject("SP")) will return null.
map.contains(new SPObject("SP")) will return false.
This is the result, if the hashCode/equals contract is not handled properly.
如果hashCode()和equals()没有在SPObject类中正确地编写,问题就在下面。输入两个条目-新的SPObject(“SP”)和新的SPObject(“SP”)。它们被视为不同的对象,并成功地存储在Map中。地图。获取(新的SPObject(“SP”))将返回null。地图。包含(新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.
#5
0
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. 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.
hashCode背后的基本思想是一个实体,它知道一个对象已经报告了一个hashCode值,它与其他对象有权利假定对象是不相等的,而不需要进一步检查它们。因为整数支持与等价相关的各种公理,一个实体可能知道两个哈希码在没有直接比较的情况下是不同的。例如,知道其中一个已经报告了偶数,而另一个奇数则表示它们不能匹配。这样的假设通常允许实体快速识别大量的集合,这些集合不可能包含被查找的对象,因此不需要检查这些区域。
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. 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.
对于hashCode和equals的引用“需求”都包含一个未声明的前提:在X.equals(Y)报告为真的情况下,一个人不希望实体错误地认为它是假的。一般来说,对代码进行错误的假设是非常糟糕的,因此,一个人不希望实体对对象的平等做出错误假设的前提是合理的。研究指南引用了这样一个事实:如果两个对象的hashcode不相等,那么它们将被假定为不相等的;要使这种假设与现实相符,就需要它们是不平等的。JavaDoc实际上暗示了这样一个事实:如果两个对象是相等的,并且一个想要避免实体假设它们不会,并且没有注意到它们是,那么就必须确保一个返回的hashCode值也会被另一个返回。