Equals and HashCode Part IV: The Implementation

Over the last few posts we have been looking at the equals and hashcode methods by way of implementing our own HashMap, and followed up with how to unit test them. Now that we have an understanding of the equals and hashcode contract, and have a good way to test implementations, let’s look at some ways to actually implement them.

Roll Your Own

It’s not recommended to write your own from scratch since there are libraries and other ways to do this that take the guesswork out of how to best implement it. Nonetheless, implementing your own can at least be instructional.

I recommend some foundational reading just to have an understanding of the issues involved. To really have a good grasp of implementation concerns, I highly recommend reading Josh Bloch’s Effective Java. In the 2nd edition, Chapter 3 Items 8 and 9 (“Obey the general contract when overriding equals” and “Always override hashCode when you override equals”) he covers equals and hashCode implementation concerns in great detail, and it is a must read for anybody who’s implementing equals and hashCode.

IDE auto generate

Better than writing your own code is to let your IDE generate it for you. Any of the major IDE’s (Netbeans, Eclipse, IntelliJ) will do this. For example, in Netbeans you can navigate to Source > Insert Code > “equals() and hashCode() …” and select the fields to be included.

The positive side is that the generated methods will take care of all the boilerplate such as checking for null, checking class equivalency, and so on. The knowledge of how to use fields to best generate these methods has been collected and refined over the years, and baked in to the IDE itself for your benefit. It’s not a bad idea to leverage that knowledge and experience instead of going out on your own.
The downside is that you need to remember to regenerate these methods if you add a member variable. Also if you prefer using a lightweight IDE you may not have source generation capabilities available to you.

Apache Commons

Another alternative, and one that is perhaps easier to read than IDE-generated code (and perhaps more consistent across IDE’s) is the capability provided by Apache Commons Lang. You can use EqualsBuilder and HashCodeBuilder to implement these methods very effectively. The details for using them are in the javadocs, but in a nutshell you can just write code like this:

public class Person {
   String name;
   int age;
   boolean smoker;
   ...

   public int hashCode() {
     // you pick a hard-coded, randomly chosen, non-zero, odd number
     // ideally different for each class
     return new HashCodeBuilder(17, 37).
       append(name).
       append(age).
       append(smoker).
       toHashCode();
   }
 }

This gets around the requirement to depend on your IDE, but you still need to remember to modify these methods yourself if you add a new member variable.

Project Lombok

Finally, there is Project Lombok. Using the @EqualsAndHashCode annotation you essentially get equals and hashCode for free. The accumulated knowledge about implementation is embedded in the library for you to leverage. And can even ignore having to modify those methods if you add new member variables! So this solves all of our problems, right? Well… kind of.

For one thing, you should always be aware of what equals and hashCode are doing in relation to your member variables, so you will still need to at least consider if new members should be included or excluded in those methods. So no matter what technique you use, you need to keep those methods in mind.

Another thing about Project Lombok is that there are some caveats for using the library. You should carefully consider the costs and benefits of the library and evaluate whether use of this library is right for you.

Conclusion

Whether you roll your own, generate the code, or use a library: knowing your options and the related tradeoffs are a foundational part of being a good Java developer. Again, I encourage everybody to read up on it, understand it, and at least be able to recall the possibilities for implementing these methods. Your code – and your customers – will thank you!

Happy HashCoding!

Advertisements

Leave a comment

Filed under Software Engineering

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s