覆盖hashCode()不起作用

use*_*956 0 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我测试它并做

    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));
Run Code Online (Sandbox Code Playgroud)

输出就是这个

false
true
Run Code Online (Sandbox Code Playgroud)

为什么我的hashCode不起作用?

Sot*_*lis 7

Point(int x, int y) {
    x = x;
    y = y;
}
Run Code Online (Sandbox Code Playgroud)

您将x本地参数变量分配给自身.同样的y.这些都是无操作.

使用

Point(int x, int y) {
    this.x = x;
    this.y = y;
}
Run Code Online (Sandbox Code Playgroud)

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


正如其他人所说,你不应该这样做

Point p = (Point) o;
Run Code Online (Sandbox Code Playgroud)

不知道是否o是一个Point.ClassCastException如果它不能分配给它,它将抛出一个Point.而是使用

if (o instanceof Point)
    return false;
Run Code Online (Sandbox Code Playgroud)

要么

if (o.getClass() != Point.class) 
    return false;
Run Code Online (Sandbox Code Playgroud)

在铸造之前.请注意,上述两种方法不相同.在大多数情况下,您可以使用第一个,但如果Point要使用子类,则使用第二个.