Override equals and hashCode method in Java

In this post, we will see how to override equals and hashCode method in Java.


 

The general contract for overriding equals is proposed in item 8 of Josh Bloch’s Effective Java. Ideally equals method should satisfy the following conditions. It should be:

Reflexive: A non-null object should be equal to itself i.e. x.equals(x) == true.

Symmetric: If the first object is equal to a second object, then the second object should be equal to the first object. i.e. x.equals(y) == true if and only if y.equals(x) == true.

Transitive: If the first object is equal to a second object and the second object is equal to a third object, then the first object should be equal to the third object. i.e. x.equals(y) == true and y.equals(z) == true, then x.equals(z) == true.

Consistent: Multiple calls to equals (x.equals(y) or y.equals(x)) must return the same value at any point of time unless either x or y is modified.

 
Item 9 in Josh Bloch’s Effective Java always asks us to override hashCode() method if the class overrides equals(). Otherwise, the class object will not behave properly on hash-based collections like HashMap, HashSet, and Hashtable (see why?). Also, keep in mind that

1. If equals() returns true for two objects, then hashCode() method should also return the same value. i.e. if a.equals(b) == true and b.equals(a) == true, then a.hashCode() == b.hashCode().

2. If equals() returns false for two objects, then hashCode() method should return different values. i.e. if a.equals(b) == false or b.equals(a) == false, then a.hashCode() != b.hashCode().

 
Now let’s discuss various ways to override equals and hashCode method in Java.

 

1. Java 6 and less

 
Here’s recommended process to compute hashCode manually before Java 7:

 
1. Initialize hashcode by a non-zero value, ideally a prime number, say 17.

2. For all relevant fields from the object (which are used in equals method for equality), compute the hashcode c by following below rules and append c into the result using prime multiplier 37 as
result = 31 * result + c.

• For primitve fields, compute (int)f for byte, char or short, (f ? 1 : 0) for a boolean,
(int)(f ^ (f >>> 32)) for a long (>>> is unsigned right shift operator) and Float.floatToIntBits(f) and Double.doubleToLongBits(f), for float and double respectively.

• Recursively invoke hashCode on field that is an object reference.

• If the field is an array, invoke Arrays.hashCode() method or compute hashCode for each element of the array by applying above rules.

• If the value of the field is null, return 0.

 
We should always choose a prime number in hashCode() method that results in a good hash function which produces unequal hash codes for unequal objects and uniformly distribute all possible hash values across the hash table to avoid collision.

 

Download   Run Code

Output:

true
false

 
Another option is to place all the input values into an array, and calculate hash of that array using Arrays.hashCode(Object[]) method which was introduced in Java 5 as shown below:

 

2. Java 7 and above

Java 7 introduced Objects class that provides static utility methods for computing the hash code of an object and comparing two objects.

This should be preferred over implementing our own hash function. For objects containing multiple fields, we can use Objects.hash(…) method that generates a hash code for a sequence of input values which internally uses Arrays.hashCode(Object[]) method. For Object equality, we should use Objects.equals(...) method or Objects.deepEquals(...) method to check for deep equality.

 

Download   Run Code

Output:

true
false

 

3. Guava Library

Guava Library provides Objects class that has helper functions Objects.hashCode(...) and Objects.equal(...) that works in similar way as Java 7 Objects class. It can be used before Java 7.

 

Download   Run Code

Output:

true
false

 

4. Apache Commons Lang

Apache Commons Lang library also provides useful helper classes EqualsBuilder and HashCodeBuilder, which strictly follows the rules laid out in Josh Bloch’s Effective Java.

 

Download

Output:

true
false

 

5. Using a Java IDE

It tedious and error-prone to implement equals() and hashCode() by hand, especially for large POJO’s. Most Java IDEs provide option to auto-generate equal() and hashCode() methods where we can also easily skip fields we don’t want to consider them for equality and hash code calculation.

For instance, below code is auto-generated by eclipse using Source > Generate equal() and hashCode():

 

Download

 
Similarly, below code is auto-generated by IntelliJ IDEA using Code > Generate > equal() and hashCode():

 

Download

 

Please note that these generated methods are not automatically updated when we change any field in the POJO. So we might need to regenerate the methods.

 
Also see: Why do we need to Override equals and hashcode methods in Java

 
References: Josh Bloch’s Effective Java

 
Thanks for reading.




Please use ideone or C++ Shell or any other online compiler link to post code in comments.
Like us? Please spread the word and help us grow. Happy coding 🙂
 





Leave a Reply

Notify of
avatar
wpDiscuz