Reputation: 755
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?
Upvotes: 0
Views: 553
Reputation: 280102
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.
Upvotes: 7