[英]Why does not Java HashSet.equals() check for object equality?
I've come to this phenomenon this morning, the equals
method in Set
does not check for value equality of the element while List
does. 我今天早上遇到了这种现象, Set
中的equals
方法不检查List
元素的值相等性。 This is not in accordance with the java doc. 这与java doc不符。
Set<MyClass> s1 = new HashSet<>();
Set<MyClass> s2 = new HashSet<>();
Set<MyClass> s3 = new HashSet<>();
Set<MyClass> s4 = new HashSet<>();
List<MyClass> l1 = new ArrayList<>();
List<MyClass> l2 = new ArrayList<>();
MyClass o1 = new MyClass();
MyClass o2 = new MyClass();
// **this gives false, and does not call MyClass.equals().**
s1.add(o1);
s2.add(o2);
boolean setCompareWithDifferentObjects = s1.equals(s2);
// this gives true, and also does not call MyClass.equals().
s3.add(o1);
s4.add(o1);
boolean setCompareWithSaveObjects = s3.equals(s4);
// this give true, and MyClass.equals() is called.
l1.add(o1);
l2.add(o2);
boolean listCompare = l1.equals(l2)
I've done some research. 我做了一些研究。 According to this Java doc for Set , HashSet equals , HashSet containsAll , HashSet contains , it will use (o==null ? e==null : o.equals(e)) to check whether the elements are equal. 根据此Java文档Set , HashSet等于 , HashSet containsAll , HashSet包含 ,它将使用(o == null?e == null:o.equals(e))检查元素是否相等。 So why is this happen? 那么为什么会这样呢? Can anyone give me some hint on this? 有人可以给我一些提示吗?
Thanks! 谢谢!
----------Answer to this question can be found here ----------- ----------这个问题的答案可以在这里找到-----------
What issues should be considered when overriding equals and hashCode in Java? 在Java中重写equals和hashCode时应考虑哪些问题?
I overrided equals() but not hashCode()... 我覆盖了equals()但没有覆盖hashCode()...
btw, the same set comparison worked in groovy, even if hashCode() is not overriden. 顺便说一句,即使没有覆盖hashCode(),相同的集合比较也可以正常工作。
HashSet
includes a number of optimizations that can explain all of this: first, if two objects are put into different buckets by their hash codes, or if they have different hash codes at all, they may skip the equals
call. HashSet
包含许多可以解释所有这些问题的优化:首先,如果两个对象通过其哈希码放入不同的存储桶中,或者如果它们完全具有不同的哈希码,则它们可以跳过equals
调用。 This is allowed by the contract of Object.hashCode
; 这是由Object.hashCode
的合同允许的; if two objects have different hash codes then they are not allowed to .equals
to each other. 如果两个对象具有不同的哈希码,则不允许它们彼此.equals
。
For the other case, HashSet
takes advantage of the contract of .equals
that specifies that if two objects are ==
to each other, then they must be .equals
to each other. 在另一种情况下, HashSet
利用.equals
协定的优势,该协定指定如果两个对象彼此==
,则它们必须彼此.equals
。 Part of HashSet
's implementation here checks if the elements are ==
, and if they are, it skips calling .equals
. HashSet
的实现的一部分在此处检查元素是否为==
,如果是,则跳过对.equals
调用。
If every method implements its contract correctly, this cannot change the semantics; 如果每种方法都能正确实现其约定,则无法更改语义; HashSet
will always behave exactly as if .equals
were being called. HashSet
行为始终与调用.equals
完全相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.