Java 如何更正hashCode()方法以正确使用HashSet集合

Java 如何更正hashCode()方法以正确使用HashSet集合,java,hashset,hashcode,Java,Hashset,Hashcode,为了确保equals和hashcode()得到很好的实现,我们必须确保以下规则 自反性 对称性 及物性 一致性 非无效 但是我下面的实现违反了规则一致性(如果我修改它的字段,x永远不会等于它本身),所以我必须做什么才能使这个测试正确运行 public class TestHashCode { public class Point { public int x; public int y; public Point(int x, int y) {

为了确保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));
}
公共类TestHashCode{
公共课点{
公共int x;
公共智力;
公共点(整数x,整数y){
这个.x=x;
这个。y=y;
}
公共int hashCode(){
int hash=3;
hash=97*hash+this.x;
hash=97*hash+this.y;
返回散列;
}
公共布尔等于(对象obj){
//由netbeans IDE生成的代码
}
}
@试验
公开考试资格(){
点x=新点(1,1);
Set pointsAsSet=new HashSet();
pointsAsSet.add(x);
x、 x=3;
Assert.assertTrue(pointsAsSet.contains(x));
}

}您不能对
哈希集
的成员(参与
等于
哈希码
的实现)的属性进行变异,并期望其正常工作

或者不修改这些属性,在修改元素之前从
哈希集中删除该元素,然后重新添加:

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));
点x=新点(1,1);
Set pointsAsSet=new HashSet();
pointsAsSet.add(x);
...
点集。移除(x);
x、 x=3;
pointsAsSet.add(x);
...
Assert.assertTrue(pointsAsSet.contains(x));

另一种选择是,如果在
类中有一些唯一的不可变属性,则可以将其用作
哈希映射
(例如
哈希映射
)中的键,这样就不需要
类来重写
equals
哈希代码
,可能建议
公开最终int x;公共财政-不可变对象,允许共享。