想象一下,我们有这段代码。
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(插入时的那个)。因此,在插入后更改元素会更改其原始 hashCode,因此 contains() 将返回 false。
在我看来,这是一种非常不直观的行为。
你怎么看?