I have a class where I have overridden both the hashCode method as well as the equals method. The equals method behaves as I would expect it to, however the hashCode method
The problem is that you have provided a wrong equals
: it should be equals(Object)
, not equals(Car)
.
Essentially, you have provided an overload instead of an override, so HashMap
keeps calling the equals
from the base class.
Fixing this problem is simple: add an override that does the cast, and calls the equals
method that you wrote, like this:
@Override
public boolean equals(Object other) {
return (other instanceof Car) && equals((Car)other);
}
Note the use of @Override
annotation. It helps Java help you spot issues like this automatically.
Note: with this problem out of the way, consider implementing your hashCode
method in a more "frugal" way. Rather than creating a throw-away (this.getCarName() + this.getCarModel())
string simply for the purpose of obtaining its hash code, consider rewriting the method as follows:
public int hashCode() {
return 31*getCarName().hashCode() + getCarModel().hashCode();
}
or in Java 1.7+ you could write
public int hashCode() { // Thanks, fge, for a nice improvement!
return Objects.hash(carName, carModel);
}
The problem is not with .hashCode()
; the problem is that you don't override .equals()
!
Look at your prototype:
public boolean equals(Car car)
Now have a look at the documentation for Object...
What you should override is:
public boolean equals(Object obj)
Hence the error. You did implement hashCode correctly, however you use Object
's .equals()
implementation.