This post will discuss how to override equals() and hashCode() methods 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 the 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 the equals() and hashCode() methods in Java.

1. Java 6 and less

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

 
1. Initialize hashcode by a nonzero value; ideally, a prime number, say 17.

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

  • For primitive 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 the field that is an object reference.
  • If the field is an array, invoke the Arrays.hashCode() method or compute hashCode for each array element by applying the above rules.
  • If the value of the field is null, return 0.

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

Download  Run Code

Output:

true
false

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

2. Java 7 and above

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

We should prefer this over implementing our own hash function. For objects containing multiple fields, we can use the Objects.hash(…) method that generates a hash code for a sequence of input values, which internally uses the 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. Using Guava Library

Guava library provides Objects class that has helper methods Objects.hashCode(…) and Objects.equal(…) that works similarly as Java 7 Objects class. We can use it before Java 7.

Download Code

Output:

true
false

4. Using Apache Commons Lang

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

Download Code

Output:

true
false

5. Using a Java IDE

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

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

Download Code

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

Download Code

 
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.

That’s all about overriding equals and hashCode methods in Java.