このコードがあると想像してください。
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 を返します。
私の意見では、これは非常に非直感的な動作です。
どう思いますか?