Performance Zone is brought to you in partnership with:

Senior Java developer, one of the top stackoverflow users, fluent with Java and Java technology stacks - Spring, JPA, JavaEE. Founder and creator of http://computoser.com and http://welshare.com . Worked on Ericsson projects, Bulgarian e-government projects and large scale recruitment platforms. Member of the jury of the International Olympiad in Linguistics and the Program committee of the North American Computational Linguistics Olympiad. Bozhidar is a DZone MVB and is not an employee of DZone and has posted 90 posts at DZone. You can read more from them at their website. View Full User Profile

Generating equals(..), hashCode() and toString()

08.13.2014
| 4729 views |
  • submit to reddit

You most probably need to override hashCode()equals(..) and toString() – I won’t go into details when and why, but you need that (ok, just a reminder – always implement hashCode and equals together, and you most likely need to implement these methods if you are going to look up objects of a given class in a hashmap or an arraylist). And you have plenty of options to do it:

  • Manually implement the methods – that’s sort-of ok for toString() and quite impractical with hashCode() and equals(..). Unless you are pretty certain that you want a custom, well-considered hash function, then you should rely on another, more practical mechanism
  • Use the IDE – all IDEs can generate the three methods, asking you to specify the fields you want to base them on. The hash function is usually good enough, and the rest just saves you from the headache of writing boilerplate comparisons, ifs and elses. But when you add a field, you shouldn’t forget to regenerate the methods.
  • commons-lang – there’s EqualsBuilderHashCodeBuilder and ToStringBuilderthere, which help you write the methods quickly, either with manualappend(field).append(field), or with reflection, e.g. reflectionEquals(..). Adding a field again requires modifications, and it’s easy to forget that.
  • guava – very similar to commons-lang, with all the pros and cons. Guava has Objectsand MoreObjects, with helper functions for equals(..) and hashCode and a builder for toString() – you still have to manually add/compare each field you want to include.
  • project lombok – it plugs into the compiler and turns some annotations into actual implementations, sparing you writing the biolerplate code completely. For example, if you annotated the class with @EqualsAndHashCode, Lombok will generate the two methods with all the fields in the class (you can customize that). The other annotations are @ToString@Value (for immutables), @Data (for value-objects). You just have to put a jar on your compile time classpath, and it should work.

Which of these should you use? I generally exclude the manual approach, as well as guava and commons-lang – they require too much manual work for a task that you shouldn’t need to care in 99% of the cases. The reflection option with commons-lang sounds interesting, but also sounds like performance overhead.

I’ve always used the IDE – the only downside of this is that you have to regenerate them. Sometimes you may forget and that may yield unexpected behaviour. But apart from that, it’s quick and robust approach.

Project lombok seems to eliminate the risk of forgetting to regenerate, but that sometimes has another side effect – you may not need to automatically include all new fields, and you can forget to exclude them. But my personal reluctance to use lombok is based on a sort-of a superstition – it does “black magic” by plugging into the compiler. It does work, but it you don’t know how exactly it manages to handle both eclipse compiler, javac, IntelliJ compiler; will it always work with maven, including your CI environment? Will it work through a major/minor compiler version upgrade? Obviously it does, and I have no rational argument against it. And it has some more useful features as well.

So, it’s up to you to pick either of the two approaches. But do not implement it manually, and I don’t think the helper functions/builders are that practical.

Published at DZone with permission of Bozhidar Bozhanov, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Martin Farrell replied on Fri, 2014/08/15 - 3:55am

I have the same issue with Lombok that you have cited - i like to know whats going on. The annotations seem like a good idea, but I like to see my equals, hashcode's and toStrings. I also think its important for developers to see this code as they apply a number of important rules in Java. With this in mind I just let the IDE create the methods

 


 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.