3

このコードがあると想像してください。

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 から生成されたものです。

問題は、2 つのセットの要素を変更する前に、セットが等しいことです。e1.hashCode() == e2.hashCode() と e1.equals(e2).

2 つの HashSet を比較するとき、Java は要素の元の hashCode (挿入時のもの) を使用すると推測しています。したがって、挿入後に要素を変更すると、元の hashCode が変更されるため、contains() は false を返します。

私の意見では、これは非常に非直感的な動作です。

どう思いますか?

4

1 に答える 1