What if equals and hashcode contract is not followed, in Java?

Ankit Wasankar
3 min readJun 29, 2023

--

You may already know the contract between a hashcode and equals. But, if an interviewer asks you what can go wrong if you don’t follow the equals and hashcode contract. Would you be able to give an example ? If no, this blog is for you.

We will cover these questions in details here

  1. What is the equals and hashcode contract ?
  2. What can go wrong if I don’t follow equals and hashcode contract ?

You can watch my video for more in depth info with visualizations.

#java #javainterviewquestions #interviewquestions #equals #hashcode

1. What is the equals and hashcode contract ?

Contract is — If two objects are equal according to the equals() method, their hashCode() values must be the same.

If two objects are not equal according to the equals() method, their hashCode() values can be the same or can be different.

2. What can go wrong if I don’t follow equals and hashcode contract ?

If you don’t follow the equals() and hashCode() contract when using objects in a HashMap, you may encounter unexpected behavior, such as duplicate entries. Here’s an example to illustrate the issue:

class Person {
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

// Equals method without overriding hashCode
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Person person = (Person) obj;
return age == person.age && name.equals(person.name);
}
}

Now, let’s create two Person objects that are equal according to the overridden equals() method but do not override the hashCode() method:

Person person1 = new Person("Alice", 25);
Person person2 = new Person("Alice", 25);

If we attempt to add both objects to a HashMap:

Map<Person, String> map = new HashMap<>();
map.put(person1, "Value 1");
map.put(person2, "Value 2");

According to the equals() method, person1 and person2 are considered equal because their names and ages are the same. However, since we did not override the hashCode() method, the default hashCode() implementation from the Object class is used.

Due to the default hashCode() implementation, person1 and person2 will have different hash codes, and the HashMap will treat them as distinct keys. As a result, we end up with two entries in the HashMap:

{Person@hashcode1: "Value 1", Person@hashcode2: "Value 2"}

In this case, we intended to have only one entry in the HashMap because the objects are equal according to the equals() method. However, due to the mismatch between the equals() and hashCode() implementations, the HashMap treats them as separate keys.

This situation violates the contract between equals() and hashCode(), as equal objects should have the same hashCode(). It leads to incorrect behavior in HashMap operations, such as retrieval, removal, or replacement of objects, as they may not work as expected when searching for objects based on equality.

Equals and Hashcode Contract — Youtube video thumbnail — https://www.youtube.com/watch?v=CpVALR9HeTE

--

--