If we override equals(), then we may or may not override hashcode(). (Java override equals | Java override hashcode)

In Java, equals() is implemented in the Object class by default. This method is used to compare two objects. The default implementation just simply compares the memory addresses of the objects. You can override the default implementation of the equals() method defined in java.lang.Object. If you override the equals(), you MUST also override hashCode(). Otherwise, a violation of the general contract for Object.hashCode() will occur, which results in unexpected behavior when your class is in conjunction with all hash-based collections.

This is a general contractor in Java programming that “whenever you override equals(), override hashcode() also”.

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equal comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals() method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals() method, then calling the hashCode() method on each of the two objects must produce distinct integer results.

Consider the following two examples. In the 1st example, I have overridden equals() only, and in the 2nd one I have implemented equals() and hashCode(), see the differences.

Example 1: (java override equals() only)

public class HashCodeSample {

private int id;
private int code;
private String name;
public HashCodeSample(int id, int code, String name) {
super();
this.id = id;
this.code = code;
this.name= name;
}

public boolean equals(Object obj) {
if (!(obj instanceof HashCodeSample))
return false;
if (obj == this)
return true;
return this.id == ((HashCodeSample) obj).id &&
this.code == ((HashCodeSample) obj).code;

}

public static void main(String[] arr) {
Map<HashCodeSample,String> m = new Hashtable<HashCodeSample,String>();
HashCodeSample h1 = new HashCodeSample(1234,8, “Test1?);
HashCodeSample h2 = new HashCodeSample(1234,8, “Test2?);
m.put(h1,”Hashcode Test”);
System.out.println(m.get(h2));
}
}

Compile and run this code and this will return null.

Example 2: (java override equals() and java override hashcode())

public class HashCodeSample {

private int id;
private int code;
private String name;
public HashCodeSample(int id, int code, String name) {
super();
this.id = id;
this.code = code;
this.name= name;
}

public boolean equals(Object obj) {
if (!(obj instanceof HashCodeSample))
return false;
if (obj == this)
return true;
return this.id == ((HashCodeSample) obj).id &&
this.code == ((HashCodeSample) obj).code;

}

public int hashCode() {
int result = 0;
result = (int)(id/5) + code;
return result;
}
public static void main(String[] arr) {
Map<HashCodeSample,String> m = new Hashtable<HashCodeSample,String>();
HashCodeSample h1 = new HashCodeSample(1234,8, “Test1?);
HashCodeSample h2 = new HashCodeSample(1234,8, “Test2?);
m.put(h1,”Hashcode Test”);
System.out.println(m.get(h2));
}
}

Compile and run this code and this will return the Hashcode Test

What is wrong with the 1st example? The two instances of HashCodeSample are logically equal according to the class’s equals method. Because the hashCode() method is not overridden, these two instances’ identities are not in common with the default hashCode implementation. Therefore, the Object.hashCode returns two different numbers instead. Such behavior violates the “Equal objects must have equal hash codes” rule defined in the hashCode contract.

Have questions? Contact the technology experts at InApp to learn more.