为了确保 equals 和 hashcode() 得到很好的实现,我们必须确保以下规则
- 自反性
- 对称性
- 传递性
- 一致性
- 非无效
但是我的以下实现违反了规则一致性(如果我修改其字段,x将永远不会等于它自己),那么我必须做什么才能使这个测试正确运行?
public class TestHashCode {
public class Point {
public int x;
public int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int hashCode() {
int hash = 3;
hash = 97 * hash + this.x;
hash = 97 * hash + this.y;
return hash;
}
public boolean equals(Object obj) {
// generated code by netbeans IDE
}
}
@Test
public void testEquals() {
Point x = new Point(1, 1);
Set<Point> pointsAsSet = new HashSet<>();
pointsAsSet.add(x);
x.x = 3 ;
Assert.assertTrue(pointsAsSet.contains(x));
}
}
最佳答案
您无法改变 HashSet
成员的属性(参与 equals
或 hashCode
的实现)并期望它能够工作。
要么不要改变这些属性,从 HashSet
中删除该元素在改变它之前,稍后重新添加它:
Point x = new Point(1, 1);
Set<Point> pointsAsSet = new HashSet<>();
pointsAsSet.add(x);
...
pointsAsSet.remove(x);
x.x = 3 ;
pointsAsSet.add(x);
...
Assert.assertTrue(pointsAsSet.contains(x));
作为替代方案,如果您的 Point
中有一些独特的不可变属性类,您可以将其用作 HashMap
中的键(例如 HashMap<Integer,Point>
),然后您将不需要 Point
要覆盖的类 equals
和hashCode
.
关于java - 如何更正 hashCode() 方法以正确使用 HashSet 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47811941/