Getting equals() and hashCode() right
September 5th, 2007 by RyanWhenever you override the equals() and hashCode() functions of a class, it is very important that you do so correctly. Bugs in these functions are often quite insidious, because they will not fail catastrophically. Your application will compile and probably do something reasonable, passing any smoke test you throw at it. However, the output will be subtly incorrect. Moreover, by the time you realize that some has gone wrong, there is little information about what caused the error. This is because the error occurred 10 steps ago, nested five levels deep, when a member of a HashSet went MIA. While a NullPointerException is normally trivial to diagnose and fix, you can easily lose several hours tracking down an equals()/hashCode() bug.
There are many excellent tutorials out there on equals() and hashCode(). The best source is probably Items 7 and 8 of Effective Java by Josh Bloch, and we have a couple copies of this book floating around the office. A good online tutorial is Java theory and practice: Hashing it out, by another Java guru, Brian Goetz.
To test your understanding, make sure that you can answer the following questions. I often ask variants of the first two during interviews. The third comes from an error we’ve seen more than once in our code base.
- Suppose we have a Media class, composed of title and contents fields. What can go wrong if equals() is based on both fields, while hashCode() is based solely on title?
- Conversely, what can go wrong if hashCode() is based on both fields, but equals() is based solely on title?
- Consider a class A which overrides equals() and hashCode(). If you create a class B which extends class A, and use Eclipse to generate your equals() and hashCode() functions for class B, then the output of class B’s hashCode() function will depend on the value of super.hashCode(). What happens if you refactor class B so that it no longer extends class A?


October 5th, 2007 at 8:48 am
Another good question to add to your list.
How would you allow an object with ALL mutable fields to correctly be placed in a hash collection?
I ran into this once with a server person passing up a Hibernate object and he was using mutable fields for his hashCode.
While a solution for this problem totally destroys the hashes performance characteristics, sometimes you have to use this hack.
BTW
My answer was have hashCode() return .class.getName().hashCode()
This basically puts everything in the same hashbucket of this object type. Not ideal but in certain edge cases this was the best solution I could come up with.