java - 更改集合中的元素会更改 'equals' 语义

标签 java equals hashset

假设我们有这段代码。

public class HashAddAfter {
    private class A {
        public int value;
        public A(int value) {
            this.value = value;
        }
        public void setValue(int value) {
            this.value = value;
        }
        // Code for hashCode()...
        // Code for equals()...
    }

    Set<A> list1 = new HashSet<A>();
    Set<A> list2 = new HashSet<A>();

    public static void main(String[] args) {
        HashAddAfter x = new HashAddAfter();

        A e1 = x.new A(1);
        A e2 = x.new A(1);

        x.list1.add(e1);
        x.list2.add(e2);

        System.out.println(x.list1.equals(x.list2));   // true

        e1.setValue(4);
        e2.setValue(4);

        System.out.println(x.list1.equals(x.list2));   // false
    }
}

由于空间限制,我没有放 hashCode() 和 equals() 的代码,但它是从 Eclipse 生成的代码。

问题是在改变两个集合中的元素之前,集合是相等的。在更改它们的值(每个值都相同)后,集合不再相等,尽管 e1.hashCode() == e2.hashCode() 和 e1.equals(e2)。

我猜测在比较两个 HashSet 时,Java 使用元素的原始 hashCode(插入时的那个)。因此,在插入后更改元素会更改其原始哈希码,因此 contains() 将返回 false。

在我看来,这是一种非常不直观的行为。

你怎么看?

最佳答案

这正是预期的行为。 Set 实现不可能知道元素的 hashCode 已更改,因此它无法采取任何措施来抵御这种可能性。

来自集合 Javadoc :

Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set. A special case of this prohibition is that it is not permissible for a set to contain itself as an element.

关于java - 更改集合中的元素会更改 'equals' 语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16402970/

相关文章:

Java SortedSet + Comparator,与equals()一致性问题

java - 无论顺序如何,Hashset 上的 .equals 是否返回 true?

c# - SomeObjects 的 HashSet 和包含带有 int 参数的函数

java - 即使文件位于同一个包中,也找不到这样的文件或目录

java - Apache Tomcat 7 无法启动

java - 在 JAXB 中处理 CDATA

java - 如何使 spring boot 嵌入式 tomcat 为基本 url 返回 200 OK?

java - 合并两个不同列表对象的列表,将对象的内容放入第三个对象列表中,其中包含前两个Java中的字段

java - ArrayList .contains() 有时为真,有时为假

Java/JUnit - 比较两个多项式对象