Tuesday, 29 October 2013

Inside Story Of Equals and Hashcode methods


How Equals and Hashcode Works


Steps to Override equals method in Java:
1) Do this check -- if yes then return true.
2) Do null check -- if yes then return false.
3) Do the instanceof check, if instanceof return false than return false from equals in Java , after some research I found that instead of instanceof we can use getClass() method for type identification because instanceof check returns true for subclass also, so its not strictly equals comparison until required by business logic. But instanceof check is fine if your class is immutable and no one is going to sub class it. For example we can replace instanceof check by below code
if((obj == null) || (obj.getClass()!= this.getClass()))
return
false;
4) Type cast the object; note the sequence instanceof check must be prior to casting object.
5) Compare individual attribute starting with numeric attribute because comparing numeric attribute is fast and use shortcircuit operator for combining checks. If first field does not match, don't try to match rest of attribute and return false. It’s also worth to remember doing null check on individual attribute before calling equals() method on them recursively to avoid NullPointerExceptionduring equals check in Java.

Common Errors while overriding equals in Java.
1)    Instead of overriding equals() method programmer overloaded it.
2)    Second mistake I have seen while overriding equals() method is not doing null check for member variables which ultimately results in NullPointerException in Javaduring equals() invocation.
3)    Third common mistake is not overriding hashCode method in Java and only overriding equals() method. You must have to override both equals() and hashCode() method in Java
4)    Last common mistake programmer make while overriding equals() in Java is not keeping equals() and compareTo() method consistent which is a non formal requirement in order to obey contract of Set to avoid duplicates.

Writing JUnit tests for equals method in Java
·         testReflexive() this method will test reflexive nature of equals() method in Java.
·         testSymmeteric() this method will verify symmetric nature of equals() in Java.
·         testNull() this method will verify null comparison and will pass if equals method returns false.
·         testConsistent() should verify consistent nature of equals method in Java.
·         testNotEquals() should verify if two object which are not supposed to equals is actually not equal, having negative test cases in test suite is mandatory.
·         testHashCode() will verify that if two objects are equal by equals() method in Java then there hashcode must be same. This is an important test if you are thinking to use this object as key in HashMap or Hashtable

5 Tips on writing equals method in Java
Here are some tips to implement equals and hashCode method in Java, this will help you to do it correctly and with ease:
1) Most of the IDE like NetBeans, Eclipse and IntelliJ IDEA provides support to generate equals() and hashcode() method. In Eclipse do the right click-> source -> generate hashCode() and equals().
2) If your domain class has any unique business key then just comparing that field in equals method would be enough instead of comparing all the fields e.g. in case of our example if "id" is unique for every Person and by just comparing id we can identify whether two Person are equal or not.
3) While overriding hashCode in Java makes sure you use all fields which have been used in equals method in Java.
4) String and Wrapper classes like Integer, Float and Double override equals method but StringBuffer doesn’t override it.
5) Whenever possible try to make your fieldsimmutable by using final variables in Java, equals method based on immutable fields are much secure than on mutable fields.

Overriding hashCode method in Java
1) Take a prime hash e.g. 5, 7, 17 or 31 (prime number as hash, results in distinct hashcode for distinct object)
2) Take another prime as multiplier different than hash is good.
3) Compute hashcode for each member and add them into final hash. Repeat this for all members which participated in equals.


No comments :

Post a Comment