java - 重写 hashCode() 不起作用

标签 java equals hashcode hashset

我正在尝试使类 Point 与 HashSet 一起正常工作。这是我的 Point 类:

class Point {

    int x;
    int y;

    Point(int x, int y) {
        x = x;
        y = y;
    }

    @Override
    public int hashCode() {
        int hash = 1;
        hash = hash * 17 + x;
        hash = hash * 31 + y;
        return hash;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }
        Point p = (Point) o;
        return x == p.x && y == p.y;
    }
}

当我测试它并执行时

    HashSet<Point> h = new HashSet<Point>();
    h.add(new Point(0, 0));
    Point g = new Point(0, 1);
    System.out.println(h.equals(g));
    System.out.println(h.contains(g));

输出是这样的

false
true

为什么我的 hashCode 不起作用?

最佳答案

Point(int x, int y) {
    x = x;
    y = y;
}

您正在将本地参数变量x 分配给其自身。 y 也一样。这些都是无操作的。

使用

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

以便您将参数值分配给该字段。

<小时/>

others已经注意到,你不应该这样做

Point p = (Point) o;

不知道o是否是Point。如果它不可分配给Point,它将抛出ClassCastException。而是使用

if (o instanceof Point)
    return false;

if (o.getClass() != Point.class) 
    return false;

类型转换前。请注意,上述两种方法并不等效。在大多数情况下,您可以使用第一个,但如果 Point 意味着有子类,则使用第二个。

关于java - 重写 hashCode() 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22134928/

相关文章:

java - 我应该为我的简单流程使用内存映射文件吗?

java - 如何在按下键盘按钮时执行一项操作而不是循环

java - 为什么这个 .equals() 代码示例返回 "false"?

java - 字符串什么时候缓存它的哈希码?是在 String 对象创建期间还是在调用 hashcode 方法后?

java - 创建 hashCode() 方法 - Java

java - 如何在java中使用MessageDigest类?

JAVA Eclipse "accessor"无法解析为变量

java - Derby 战的直播结果

java - 为什么我在 Java HashMap 中得到重复的键?

java - 字符串比较应该相等时却不相等