Введите следующий класс:
public class Member {
private int x;
private long y;
private double d;
public Member(int x, long y, double d) {
this.x = x;
this.y = y;
this.d = d;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = (int) (prime * result + y);
result = (int) (prime * result + Double.doubleToLongBits(d));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Member) {
Member other = (Member) obj;
return other.x == x && other.y == y
&& Double.compare(d, other.d) == 0;
}
return false;
}
public static void main(String[] args) {
Set<Member> test = new HashSet<Member>();
Member b = new Member(1, 2, 3);
test.add(b);
System.out.println(b.hashCode());
b.x = 0;
System.out.println(b.hashCode());
Member first = test.iterator().next();
System.out.println(test.contains(first));
System.out.println(b.equals(first));
System.out.println(test.add(first));
}
}
Он производит следующие результаты: 30814
29853
false
true
true
Поскольку hashCode зависит от состояния объекта, он больше не может быть восстановлен должным образом, поэтому проверка на сдерживание не выполняется. HashSet больше не работает должным образом. Решением было бы сделать Member неизменным, но это единственное решение? Должны ли все классы, добавленные в HashSets, быть неизменными? Есть ли другой способ справиться с ситуацией?
С уважением.