Changing the elements in a set changes the 'equals' semantics

♀尐吖头ヾ 提交于 2019-12-18 05:12:22

问题


Imagine that we have this piece of code.

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
    }
}

I didn't put the code for hashCode() and equals() due to space constraints, but it's the one generated from Eclipse.

The problem is that before changing the elements in the two sets, the sets are equal. After changing their values (each to the same value), the sets are not equal anymore, although e1.hashCode() == e2.hashCode() and e1.equals(e2).

I'm guessing that when comparing two HashSets, Java uses the original hashCode of the element (the one at the moment of insertion). So, changing the elements after insertion changes their original hashCode, and therefore contains() will return false.

In my opinion this is a very unintuitive behaviour.

What do you think?


回答1:


This is exactly the expected behavior. There is no possible way for a Set implementation to be aware that the hashCode of an element has changed, so there's nothing it can do to defend against that possibility.

From the Set 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.



来源:https://stackoverflow.com/questions/16402970/changing-the-elements-in-a-set-changes-the-equals-semantics

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!