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

时间:2017-12-14 11:12:45

标签: java hashset hashcode

为了确保我们的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));
}

}

1 个答案:

答案 0 :(得分:4)

您无法改变HashSet成员(参与equalshashCode的实施)并希望其有效的属性。

不要改变这些属性,在变异之前从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课程覆盖equalshashCode