Вопрос

I'm trying to make class Point work correctly with a HashSet. Here is my Point class:

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;
    }
}

When I test it out and do

    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));

The output is this

false
true

Why is my hashCode not working?

Нет правильного решения

Другие советы

In

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

You are assigning x, the local parameter variable, to itself. Same for y. These are no-ops.

Use

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

so that you assign the parameter value to the field.


As others have noted, you shouldn't do

Point p = (Point) o;

without knowing if o is a Point or not. It will throw a ClassCastException if it is not assignable to a Point. Instead use

if (o instanceof Point)
    return false;

or

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

before casting. Note that the two methods above are not equivalent. You can use the first in most cases, but use the second if Point is meant to have sub classes.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top