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

原文 标签 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));
}


}

最佳答案

您不能变异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

相关文章:

javascript - Alfresco:编写工作流程脚本以将文档复制到同一文件夹中,并继续使用新文档进行工作流程

java - spring data mongo-没有定义名为“mongoTemplate”的bean

java - 如何进一步优化代码?

c++-cli - HashSet <T>在VS2012中去哪里了?

c - suse上的crypt导致segfault

java - 验证vaadin组合框自定义输入(仅限整数)

java - 使用ArrayList <Book>存储书名

java - HashSet的顺序和JDK 7/8的区别

java - Java Maps的hashCode不正确?

c# - 在编辑行后,DataRow GetHashCode()方法的值不会更改