【问题标题】:Java TreeSet Not Working as ExpectedJava TreeSet 未按预期工作
【发布时间】:2016-09-27 11:41:34
【问题描述】:

我构建了自己的类来实现可比较(可能不相关),当我尝试使用 HashSet 来存储项目时,HashSet 有时会声称该项目在 HashSet 中,即使它不在。我认为这与参考检查有关,但我确认不是。怎么了?

顶点类equalsgetHashcode

public class Vertex implements Comparable<Vertex>{

    // some code ...

    @Override
    public boolean equals(Object obj) {
        Vertex other = (Vertex) obj;
        return this.getPosition().equals(other.getPosition());
    }


    @Override
    public int hashCode() {
        int hashCode1 = Integer.parseInt(this.getPosition().getX() + "" + this.getPosition().getY());
        return hashCode1;
    }
}

职位类别:

public class Position {
    private int x;
    private int y;


    public Position(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    @Override
    public boolean equals(Object obj) {
        Position other = (Position) obj;
        return this.x == other.x && this.y == other.y;
    }

    @Override
    public String toString() {
        //return String.format("x = %d, y = %d", x, y);
        return String.format("(%d, %d)", x, y);
    }
}

编辑:这是实现

public static void test(Vertex[][] grid) {
    TreeSet<Vertex> someSet = new TreeSet<Vertex>(){{
       add(new Vertex(new Position(3, 4), false));
        add(new Vertex(new Position(0, 5), false));
    }};
    Vertex v = new Vertex(new Position(2, 5), false);
    if (someSet.contains(v)) {
        System.out.println("error");
    } else {
        System.out.println("ok");
    }
}

上面打印error

【问题讨论】:

  • 您的哈希码不是唯一的,例如它会为两个不同的点返回相同的值,即 (2,31) & (21,3)
  • 你的钥匙是什么?您的密钥是否完全实现了 equals 和 hashcode?我
  • 您应该包含使用您发布的类的代码(即创建 HashSet 的代码)。
  • 哈希码不必是唯一的,你的有点弱,试着让它变得更好。向我们展示你是如何使用你的地图和钥匙类的。
  • 请同时添加compareTo

标签: java overriding hashcode hashset treeset


【解决方案1】:

我发现了问题所在。正如@NicolasFilotto 指出的那样,我没有提到compareTo 函数。基于a past post,TreeSet 使用hashCode,而是使用compareTo(我假设用于二进制搜索)。这就是我的测试用例失败的原因。

【讨论】:

    【解决方案2】:

    通过您的hashcode 计算,点(1,12)(11,2) 将被视为相同。

    请参阅best-implementation-for-hashcode-method 获取有关哈希码的建议。

    【讨论】:

    • 这并不违反 hashCode 的约定——允许两个不相等的对象拥有相同的 hashCode。 hashCode 的好坏是另一回事。
    • 这个我明白,但是Java不处理冲突吗?
    • @ljeabmreosn Java 处理冲突。如果您发布更多相关代码,将更容易回答您的问题。
    猜你喜欢
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    • 2012-06-29
    • 1970-01-01
    • 2017-12-27
    • 2014-05-18
    相关资源
    最近更新 更多