In Part 1 of this series we discussed how to override the equals method for any class the extends from java.lang.Object, why we would want to do so, and a few pitfalls of doing this. In this post we will look at how and why you must also override the hashCode method any time you override an object's equals' method.
So why the hype about hashCode()?
Good question. And I have an answer for you! If you take a look at the Java JDK documentation covering Object.equals you will see that one of the last things mentioned is the following:
Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
I'm not sure why
Sun decided to list this point last, but I am glad to see that the C# guys got it right and put the notice at the top of
their documentation. But I digress... the reason that this is so important is that the
hashCode method is responsible for returning an object's (you guessed it) hash code value as an integer. This hash code value is used by hash based collections such as
Hashtable,
HashMap,
HashSet, etc... for storing, retrieving, sorting, and other data structure operations.
What does that mean?
As compared to the contract inherent to theequals method, the contract defined by the hashCode method is relatively simple and straight forward. There are really only two conditions that must be met:
- The hash code value returned by the method must be the same for multiple invocations of the method during the same execution of the application, provided the object is not modified in a way that would affect the
equals method. - A corollary to the
equals method, The second requirement is that equal objects must produce the same hash code values. However, unequal objects need not produce distinct hash code values, although doing so may improve performance of collections reliant upon the hash values.
To sum it up, equal objects must produce the same hash code value as long as they are equal, however unequal objects do not need to produce distinct hash code values.
How do I implement hashCode
Similar to how we implemented hashCode our hash code calculation must involve all attributes of the class that make contribute to the equality comparison of the class. For our Car example, the following would work:
public int hashCode()
{
int hash = 7;
hash = 31 * hash +
(null == this.licensePlate ? 0 : this.licensePlate.hashCode());
hash = 31 * hash +
(null == this.vinNumber ? 0 : this.vinNumber.hashCode());
return hash;
}
Java provides an implementation of hashCode for built-in classes such as String and other wrapper classes. If you have an int data type that is part of your equals comparison you can simply add, subtract, multiply, or divide it into your hash code value.
Resources