在下面的代码中,输出显示每个对象的CONTAINS
,而注释掉匿名对象的equals()
方法导致MISSING
,这使我相信第二个相等的传递( hashCode()
- > equals()
)实际调用所提供对象的等式方法,而不是被测试集合中的对象。
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()
方法原则上应该在两个对象之间对称吗?
答案 0 :(得分:4)
HashSet
必须a.equals(b)
或b.equals(a)
。因为它们应该被写成对称的 * ,所以它选择它并不重要。
但作为参考,documentation表示:
返回
true
当且仅当此集合包含e
元素(o==null ? e==null : o.equals(e))
时才会{{1}}
<小时/> *请参阅http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#equals(java.lang.Object)。
答案 1 :(得分:1)
这是一个我们不应该担心的实现细节,因为它从未在公共API中说过它如何使用equals。就像你说的那样它应该是对称的。如果我们进入src,我们会发现它确实是passedObject.equals(storedObject)
答案 2 :(得分:-1)
Becaue AFAIK默认 Object.equals 实现使用参考比较,因此它会检查这两个引用是否引用同一个对象。
在这里,您要将字符串的实例与另一个自定义classe进行比较,它们不能相同,无论采用何种方式。