HomeAbout MeContact
Java
Equals and HashCode methods in Java
Piotr Szarpak
Piotr Szarpak
April 10, 2020
3 min
Make sure to subscribe to our newsletter and be the first to know the news.

Equals and HashCode methods in Java

In Java, every object extends java.lang.Object class. One of the main methods of this class is the equals method which as Javadoc says:

“Indicates whether some other object is ‘equal to’ this one”.

Basics

Let’s start with some basics. In its default implementation, the equals method compares references between two objects. On the other hand, it is often highly desirable to override this method to make object equality consistent with imposed business logic. Suppose we have a Person class with two attributes: “name” and “surname”:

public class Person {
private String name;
private String surname;
}

If we compare two objects of this class which have the same “name” and “surname” the result will be false, because the objects have different references.

Person person1 = new Person("John", "Kowalski");
Person person2 = new Person("John", "Kowalski");
System.out.println(person1.equals(person2)); // false

In order to make objects equal based on their attribute values, we have to override the equals method from the Person class:

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Person other = (Person) obj;
if (name == null) {
if (other.name != null) return false;
} else if (!name.equals(other.name)) return false;
if (surname == null) {
if (other.surname != null) return false;
} else if (!surname.equals(other.surname)) return false;
return true;
}

Now two objects of the Person class will be equal if they have the same “name” and “surname” value:

Person person1 = new Person("John", "Kowalski");
Person person2 = new Person("John", "Kowalski");
System.out.println(person1.equals(person2)); // true

The hashCode() method

As far as we can just override the equals method, it is strongly recommended to override the hashCode method whenever the equals method is overridden. This is associated with one of the contract’s points for hashCode method, which is stated in Javadoc as follows:

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

By default, the hashCode method returns converted to integer object memory address- taking this into account as well as the contract point mentioned above, it implies that the hashCode method has to be overridden whenever the equals method is overridden- otherwise hashCode method for every new object will return different value regardless of class attributes values and that breaks the contract.

What is even more interesting, another point of the contract for hashCode method says, that it is NOT required for two objects that are not equal, to return different value from hashCode method:

It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

To understand why is, we have to understand the hashCode method’s general purpose. HashCode method is used in data structures based on hashing, like java.util.HashMap or java.util.HashSet. Data structures based on hashing are key-value type structures. For every key, there is a generated integer, which represents the index under which the value from the key-value pair is stored. Retrieving the value for the specific key is fast- you just have to generate the hash value for the key and retrieve data from the table for the obtained index. In practice, sometimes may happen that for different input values hashCode method can return the same value- this kind of situation is called collision. Collisions are undesirable, as they make different keys to be associated with the same table index. Java solves this problem by storing in every table record not a value, but a list of values. If two different objects have the same value returned by the hashCode method, they are stored in a list, where the list is stored in a table record under the index equal to its object hashCode value:

hash struct

When data for the specific key is retrieved and the hashCode value for this key does not indicate a single value but a list of values caused by the collision, then the linear search takes place: every element of the list is compared with the key using equals method, until the key is found. Linear search is much slower than retrieving data for specific indexes from a table, therefore it is highly desirable to avoid collisions which can be achieved by implementing the hashCode method in a proper way. You can find some tips on how to implement the hashCode method on stackoverflow: link.


Tags

Share

Piotr Szarpak

Piotr Szarpak

Java passionate

Sed commodo, est quis maximus fermentum, massa ipsum euismod neque, in varius risus tellus quis lacus. Sed ac bibendum odio.

Expertise

Java > 11
DDD
Spring
Databases

Social Media

githubtwitterwebsite

Related Posts

Java Transaction API + EJB
Java Transaction API + EJB
April 10, 2020
2 min
© 2024, All Rights Reserved.
Powered By

Quick Links

Advertise with usAbout UsContact Us

Social Media