Skip navigation.
Home

Generating good hashCode() and equals(Object) methods

Before we had Eclipse 3.2M5 if you wanted a good hashCode() or equals(Object) method your only options were to read a good book on the subject and implement the method, guess and implement it yourself and find out months later it was riddled with bugs or use Jakarta Commons-Lang utility classes used to [build hashCodes|http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/builder/HashCodeBuilder.html] or perform [equals operations|http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/builder/EqualsBuilder.html] . But what if you didn't want to do any of that? What if you just wanted your IDE to be smart enough to generate new methods for you based on the properties of your class? What if indeed, this is where Eclipse 3.2M5 comes in. !!Sample Project Below is a screenshot of my sample dummy project and dummy class I created just for this tip: [http://www.eclipsezone.com/team/riyad/images/articles/hashequals/new_class.gif] I went ahead and modeled a poor-man's version of a user with all the properties I think you would need to get a relatively unique match for someone. Age, first, middle and last name. !!Generating our Identities Now let's have Eclipse generate us a hashCode and equals method based on these properties: [http://www.eclipsezone.com/team/riyad/images/articles/hashequals/generate_hashequals1.gif] Now we want to leave all the properties selected, these will all be included in the hash and equals calculations. If you didn't want certain properties included in the calculation (say maybe each User had a list of the other Users they knew, you could uncheck this and exclude it from the calculation): [http://www.eclipsezone.com/team/riyad/images/articles/hashequals/generate_hashequals2.gif] It is worth noting that the generated code from Eclipse 3.2M5 will in fact take into account null values for you, so you don't have to worry about NullPointerException s at runtime because of this code. !!Reviewing the Code Now let's look at the code that was generated for us: [http://www.eclipsezone.com/team/riyad/images/articles/hashequals/generated_methods.gif] Ok now let's check this code. Everyone break out their copies of Effective Java that they all have sitting next to them, and turn to page 36: "Always override hashCode when you override equals". You'll notice the similarities in the implementation details of the hashCode method suggested by this book and the ones Eclipse 3.2M5 generated. You'll also notice that Eclipse takes into account null values so you don't have to. Now if you have a look at the equals method you'll notice all the nice short-circuit code at the top. No need to check if things are null, no need to check if they are already equal, etc. The one thing I've always wondered about equals methods though is why not just have a hashCode check right after the preliminary basic checks? Since your hashCode already considers all the properties off your class, why not just use it? I'll admit, I didn't re-read this section of Effective Java, so it might cover why. Regardless this equals implementation looks good, considers all the properties, short-circuits incase of any nulls and does just what we want. Update #1 : As Jacob Grydholt Jensen pointed out to me you cannot use hashCode in your equals implementation because a hashCode implementation that always returns 0 is completely valid per the javadoc: It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables. Thanks Jacob! Update #2 : Will Hartung gave a good reply as to why you can never really use hash values for equality testing: As a very crude example, consider if the hashcode for a word was simply the first letter. Bill, Betty, and Bob would all share the same hashcode ('B'), but are clearly different objects. Even consider a simple String hash, where you multiply the value of each character by 31 and add it (basically just like this algorirm). After 6 characters, you're already "losing" information, assuming you have a 32 bit hashcode, as you multiply it by 31, you're shifting it roughly 5 bits. If you mutliply by 32, you would be doing exactly that, but by using the prime you preserve a bit more information. So, you can see how it's essentially impossible to get a "perfect hash" for any reasonably sized object, and that's why you can not rely on hashcode to check for two objects being identical. Thanks Will! !!Conclusion Some people may wonder what happens when you add new properties to the class and want the hashCode and equals methods to reflect that, well the answer is that you need to erase your old methods and regenerate them using the wizard again. This is just like the properties (getter/setter) generation wizards already in Eclipse. Well that is all for this tip, this is a battle I have fought many times before and had an especially hard time finding a good performant solution to the hashCode issue for my libraries that have needed to consider custom identity and equality methods. Thanks for reading. [Original Post|http://www.eclipsezone.com/eclipse/forums/t64643.rhtml]

If you are using Hibernate,

If you are using Hibernate, take care of the following issue that was discussed in the original thread {{{ I tried the Eclipse generated equals/hashCode methods on some EJB3 entities. There were two problems: 1. Hibernate creates proxy objects for loaded pojos, and of course, this.getClass() == obj.getClass() fails, where obj instanceof MyPojo would succeed. 2. Due to the lazy loading by the proxy, direct access to the data members will often fail. Instead rewriting to use the getter methods fixes this problem.}}} As such the Eclipse code is not very useful. Maybe in M6 it'll be more customizable.

In My Opinion,

In My Opinion, The EClipse generated code is not professional, but it is useful. At least it will notify the programmer that he/she should override the __equal()__ , __hashCode()__ methods. -------------%%% __Ahmed Hashim__%%%