简体   繁体   English

为什么Java HashSet.equals()不检查对象是否相等?

[英]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文档SetHashSet等于HashSet containsAllHashSet包含 ,它将使用(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.

相关问题 HashSet.equals()是否在恒定时间内运行? - Does HashSet.equals() run in constant time? java hashset中项目的相等性 - equality of item in java hashset HashSet有两个等于对象? - HashSet with two equals object? 在JAVA API中,为什么使用&#39;==&#39;而不是String.equals()方法进行相等性检查 - In JAVA API why equality check using '==' rather than String.equals() method 在哪些情况下,Java 引用相等性可能与尚未覆盖 equals() 类型的对象的 equals() 相等性不同? - In which circumstances Java reference equality could be different to equals() equality for an object of a type which has not overridden equals()? WebElement.equals() 方法如何检查相等性? - How Does WebElement.equals() Method Check for Equality? 为什么String.equals不检查char []值的相等性? - Why doesn't String.equals check for equality of char[] value? AbstractList :: equals()的JDK实现不首先检查列表大小相等 - JDK implementation of AbstractList::equals() does not check for list size equality first 为什么必须将Java中的equals()传递给Object作为参数? - Why does equals() in Java must be passed Object as a parameter? 为什么 Java 不允许在枚举中覆盖 equals(Object)? - Why Java does not allow overriding equals(Object) in an Enum?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM