When reading the book Implementation Patterns on the bus to work one morning I came across a section that talks about implementing the equals and hashcode methods in Java. I don’t know how often I have read this rule by now: “If you implement equals you also have to implement hashcode“. Otherwise you get into trouble when you try to use objects of your class as a key in a Map or Set. These two methods are basically Siamese twins that share vital organs. They can’t be separated.
Every time I implemented the twins I first created equals based on the business logic I wanted to achieve. Then I just used the standard implementation of hashcode from Joshua Bloch’s Effective Java book using the same instance variables as in equals. Pretty straight forward and in 99% of all cases totally sufficient. You just shouldn’t forget about it.
Reading about it again that day made me wonder though: If it’s so straight forward, why doesn’t the compiler do it for me? I also asked myself why I have never questioned this rule before, or anyone else for that matter. Or did someone? A bit of research should prove just that. There are in fact several ways to avoid writing equals or hashcode yourself ever again.
- Let your favorite IDE generate it for you
I can’t believe I’ve been developing in Eclipse this long and never noticed the auto-generation function for equals and hashcode.
- Use the Apache Commons builder classes
The usual suspect for convenience classes strikes again. The commons-lang library provides the classes EqualsBuilder and HashcodeBuilder that allow you to build standard equals and hashcode methods by appending the required fields to a builder instance. Alternatively, there is a method that uses reflection to determine the fields (all non-static, non-transient) at runtime.
- Use Lombok annotations
Lombok generates equals and hashcode at compile time from annotations in your source code and integrates well with Eclipse. Once you finish typing the annotation the methods even show up in the outline. Pretty neat. An additional bonus is that this boilerplate code no longer clutters your source code.
My winner clearly is Lombok. But don’t take my word for it, try it out yourself. For a more detailed comparison of the above with code examples read this review on the SpringFuse blog.