1

在下面的代码中,显示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()原则上该方法应该在两个对象之间对称吗?

4

3 回答 3

4

要么HashSet必须做a.equals(b)要么。b.equals(a)并且由于它们应该写成对称的*,所以它选择哪个并不重要。

但作为参考,文档指出:

true当且仅当此集合包含一个元素e时才返回(o==null ? e==null : o.equals(e))


* 请参阅http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#equals(java.lang.Object)

于 2013-06-11T09:10:03.863 回答
1

这是一个我们不应该担心的实现细节,因为在公共 API 中从未说过它如何使用 equals。就像你说的那样,无论如何它应该是对称的。如果我们进入 src 我们会看到它真的是passedObject.equals(storedObject)

于 2013-06-11T09:14:41.447 回答
-1

因为 AFAIK 默认Object.equals实现使用引用比较,因此它检查两个引用是否引用同一个对象。

在这里,您将字符串的实例与另一个自定义类进行比较,无论采用何种方式,它们都不能相等。

于 2013-06-11T09:11:31.093 回答