Java 用传递的对象而不是存储的项调用HashSet相等
在下面的代码中,输出显示每个对象的CONTAINS,而注释掉匿名对象的equals方法会导致MISSING,这使我相信第二个相等过程hashCode->equals实际上调用了所提供对象的equality方法,而不是正在测试的集合中的对象Java 用传递的对象而不是存储的项调用HashSet相等,java,hashset,Java,Hashset,在下面的代码中,输出显示每个对象的CONTAINS,而注释掉匿名对象的equals方法会导致MISSING,这使我相信第二个相等过程hashCode->equals实际上调用了所提供对象的equality方法,而不是正在测试的集合中的对象 List<String> strings = Arrays.asList("Hello", "there", "Qix"); HashSet<String> set = new HashSet<>(strings); fo
List<String> strings = Arrays.asList("Hello", "there", "Qix");
HashSet<String> set = new HashSet<>(strings);
for(final String s : strings)
{
boolean contains = set.contains(new Object(){
@Override
public int hashCode() {
return s.hashCode();
}
@Override
public boolean equals(Object obj) {
return true;
}
});
System.out.format("%s: %s\n",
s,
contains ? "CONTAINS" : "MISSING");
}
为什么会这样?这是因为equals方法原则上应该在两个对象之间对称吗?哈希集必须执行a.equalsb或b.equalsa。因为它们应该被写成对称的*,所以它选择哪一个并不重要
但作为参考,各国:
当且仅当此集合包含元素e且o==null时返回true?e==null:o.equalse
*请参阅。哈希集必须执行a.equalsb或b.equalsa。因为它们应该被写成对称的*,所以它选择哪一个并不重要
但作为参考,各国:
当且仅当此集合包含元素e且o==null时返回true?e==null:o.equalse
*请参阅。因为默认Object.equals实现使用引用比较,因此它会检查两个引用是否引用同一个对象
在这里,您将字符串实例与另一个自定义类进行比较,无论采用何种方式,它们都不可能相等。因为默认的Object.equals实现使用引用比较,因此它会检查两个引用是否引用同一个对象
在这里,您将字符串实例与另一个自定义类进行比较,无论采用何种方式,它们都不可能相等。这是一个我们不应该担心的实现细节,因为在公共API中从未说过它如何使用equals。就像你说的,它应该是对称的。如果我们进入src,我们将看到它实际上是passedObject.equalsstoredObject这是一个我们不应该担心的实现细节,因为它从未在公共API中说过它如何使用equals。就像你说的,它应该是对称的。如果我们进入src,我们将看到它确实是passedObject.equalstoredobject作为状态:当且仅当此集合包含元素e,使得o==null时返回true?e==null:o.equalseSo不完全清楚你在问什么;哈希集必须执行o.equalse或e.equalas。因为它们应该是可交换的,所以这不重要。这正是我要问的;使用o.等式而不是相反的推理。是否有任何性能提升或疏忽?两者都没有-应该完全任意选择哪一个,所以他们可能只是随机选择一个。值得注意的是,您正在破坏equals不变量。还应该注意,在HashSet的默认实现中,hashCode是作为初步检查调用的。状态为:当且仅当此集合包含元素e且o==null时,返回true?e==null:o.equalseSo不完全清楚你在问什么;哈希集必须执行o.equalse或e.equalas。因为它们应该是可交换的,所以这不重要。这正是我要问的;使用o.等式而不是相反的推理。是否有任何性能提升或疏忽?两者都没有-应该完全任意选择哪一个,所以他们可能只是随机选择一个。唯一值得注意的是,您正在破坏equals不变量。还应该注意的是,在HashSet的默认实现中,调用hashCode是作为初步检查。@Qix:Oops我遗漏了什么吗:Sorry您传递hashCode是因为您欺骗返回您构造为与其他对象相同的自定义实现hash-code.OK:我想知道为什么有人-1它是这样的:@Qix:Oops我错过了什么:Sorry你传递hashCode是因为你欺骗返回你的自定义实现,你构造的实现与另一个对象hash-code相同。OK:我想知道为什么有人-1它是这样的:有意义。就我个人而言,我觉得奇怪的是,他们竟然做了o.equalse passed.equalsstored,因为每个存储的对象都可以有不同的方法来判断给定的对象是否相等,而传递的对象可能无法解释每种类型。然而,如果这一点很重要的话,你在用equals来表示它不打算做的事情,应该用类似树集的东西,对吗?@Qix这并不奇怪,equals的对称性意味着o.equalse==e.equals,所以你可以自由选择。这也是为什么大多数等同于实现检查Test.GeCase= = O.GETC类,以确保它们只考虑完全相同类型的对象为相等的对象。如果考虑子类,事情会变得复杂:一个子类的对象是否可以等于一个超类的对象?超类可以认为它是相等的,但子类可能不是。非常正确,我没有想到。有道理。就我个人而言,我觉得奇怪的是他们竟然通过了
.equalsstored,因为每个存储对象都可以使用不同的方法来查看给定对象是否相等,而传递的对象可能不会考虑每种类型。然而,如果这一点很重要的话,你在用equals来表示它不打算做的事情,应该用类似树集的东西,对吗?@Qix这并不奇怪,equals的对称性意味着o.equalse==e.equals,所以你可以自由选择。这也是为什么大多数等同于实现检查Test.GeCase= = O.GETC类,以确保它们只考虑完全相同类型的对象为相等的对象。如果考虑子类,事情会变得复杂:一个子类的对象是否可以等于一个超类的对象?超类可以认为它是相等的,但子类可能不是。非常正确,我没有想到这一点。