Java hashCode() method

In this article, we will discuss the most important topic, which is the hashCode() method in Java or java hashCode() method.
Everyone knows the hashCode() method is used with equals() method to compare the objects. But how we can use it? How to override the java hashCode() method in user-defined classes.
Here is the table content of the article will we will cover this topic.

1. What is the hashCode() method or hashCode?
2. Why OR When we should Override the hashCode() method?

Java hashCode() method

What is the hashCode() method or java hashCode?

The hashCode() method is defined in Object class which is the super most class in Java. This method returns a hash code value for the object. Let’s have a look at code.

public native int hashCode();

1. It returns an integer value of the object memory address. Some programmer thinks it is the memory address of an object which is not correct. It’s the integer representation of the object’s memory address.
2. It is a native method. By means of the native method, it is written in C/C++ language. As you know, in java we can’t find the memory address of the object so that the hashCode() method is written in C/C++ that helps find the memory address.

NOTE: It is always recommended if you are overriding the hasCode() method then you must override the equals() method. We’ll discuss it in detail.

As you already know every class in java is the child of Object class. It means each class inheriting the hashCode() method from Object class.
1. Whenever a new Object is created, JVM creates a new entry of Object in memory with the corresponding hashCode.
2. The hashCode() method should return a unique value for every object.
3. If two objects are equal according to equals() method, then their hash code must be the same.

// If obj1 and obj2 are equals and returning true according to the equals() method
Obj1.equals(obj2);
// Then hashCode() of both objects must be equal.
Obj1.hashCode() == obj2.hashCode()

4. If two objects are unequal according to equals() method, their hash code may or may not be equal.

// If obj1 and obj2 are not equals and returning false according to the equals() method
Obj1.equals(obj2);
// Then hashCode() of both objects may be equal or may be not.
Obj1.hashCode() == obj2.hashCode()

Let’s take the example from the String class.
In the String class, the hashCode() method is overridden and provided the equality condition accordingly.

public int hashCode() 
{
        int h = hash;
        if (h == 0 && value.length > 0) {
            hash = h = isLatin1() ? StringLatin1.hashCode(value)
                                  : StringUTF16.hashCode(value);
        }
      return h;
}

As you can see in the above code the String class has overridden the hashCode() method. It returns the int value.

public class Student 
{
	public static void main(String[] args) 
	{
		String obj1 = "Hello";
		String obj2 = "Hello";
		boolean isStringAreEqual = obj1.equals(obj2);
		boolean isHashCodeAreEqual = obj1.hashCode() == obj2.hashCode();
		System.out.println("Is Strings are equals : "+ isStringAreEqual);
		// If value of obj1 and obj2 are equals then hashCode must be equal.
		System.out.println("Is HashCode are equals : "+ isHashCodeAreEqual);
		
		String obj3 = "hello";
		isStringAreEqual = obj2.equals(obj3);
		// If value of obj2 and obj3 are not equals then hashCode may be equal ot not
		isHashCodeAreEqual = obj2.hashCode() == obj3.hashCode();
		System.out.println("Is Strings are equals : "+ isStringAreEqual);
		System.out.println("Is HashCode are equals : "+ isHashCodeAreEqual);
	}
}

Output: Is Strings are equals : true
Is HashCode are equals : true
Is Strings are equals : false
Is HashCode are equals : false

Why OR When we should Override the hashCode() method?

The default implementation of hashCode() method is not provided in Object class. It’s a native method.
Before overriding the hashCode() method. We should understand what’s the need to override it.

Let’s try to understand with the HashSet example. As you already know HashSet stores only unique values. Because it uses the hashCode() method to store the values in the hash table.  Whenever HashSet stores the value, it compares the hash code of each object and adds it to the hash table. In Java, there are some classes that override the hashCode() method. We will see how HashSet stores unique Integer values by use of hashCode() method.

Let’s have a look at the Integer class that overrides the hashCode() method.

@Override
    public int hashCode() 
{
    return Integer.hashCode(value);
}
import java.util.HashSet;
public class HashSetExample 
{
	public static void main(String[] args) 
	{
		HashSet<Integer> setOfInteger = new HashSet<Integer>();
		setOfInteger.add(1);
		setOfInteger.add(2);
		setOfInteger.add(1);
		
		System.out.println("Size of HashSet: "+ setOfInteger.size());
	}
}

Output: Size of HashSet: 2

In the above example, we have added three Integer objects in HashSet, but it contains only two objects. How it removes the duplicity of objects?
STEP 1: When we are adding the first object in HashSet. HashSet stores it inside a bucket and links it to the value of hashcode().

setOfInteger.add(1);

STEP 2: Adding another object in HashSet and adds value as mentioned in the first step.

setOfInteger.add(2);

STEP 3: Now we are adding the same element with the same hash code is inserted into the set. It doesn’t add it. Because HashSet makes a search for an element inside it, and it generates the element’s hash code and looks for a bucket that corresponds to this hash code.HashSet stores its element in Hash Table by use of the unique key. It stores each element in memory buckets. Each bucket has a particular hash code.

setOfInteger.add(1);

Why we should use the hashCode() method

Let’s consider a new scenario. You want to store all the students in a HashSet. But you want to store only unique records and do not want any duplicate records. You can accomplish this task by the use of the hashCode() method.

First of we will see, what will be the problem if we are not overriding the hashCode() method?

import java.util.HashSet;
class Student 
{
	int rollNo;
	String name;
	String className;
	Student(int rollNo, String name, String className)
	{
		this.rollNo = rollNo;
		this.className = className;
		this.name = name;
	}
}

public class HashCodeExample
{
	public static void main(String args[])
	{
		HashSet<Student> setOfStudent = new HashSet<Student>();
		Student student = new Student(1, "Ravi", "MCA");
		Student student1 = new Student(2, "Ram", "MCA");
		Student student2 = new Student(1, "Ravi", "MCA");
		
		setOfStudent.add(student);
		setOfStudent.add(student1);
		setOfStudent.add(student2);
		
		System.out.println("Size of HashSet: "+ setOfStudent.size());		
	}
}

Output: Size of HashSet: 3

As you can see in the above example, There are only two students’ object data but the size of HashSet is 3 due to duplicate objects. Let’s try to find the reason:

STEP 1: When we are adding the object student in HashSet. JVM will store it inside a bucket and links it to the value of hashcode(). Whenever an object with the same hash code is inserted into the set, it will not make any changes.

setOfStudent.add(student);

STEP 2: But when we are adding a new object student2 with the same values(Existing Student).

setOfStudent.add(student2);

It has a different hash code, So it will be stored in a separate bucket and will be considered a totally different object. Which is not a correct thing to remove duplicate objects.

Here comes the importance of overriding hashcode(). let’s override the hashCode() method in the Student class.

Step1: Create your own class that can contain Student data.
Step 2: You just need to override the equals() and hashCode() method in your class. It is always necessary to override the hashCode() method whenever equals() method is overridden. We will discuss it later.
Step3: Override the hashCode() method and set it to be equal to the rollNo so that students who have the same rollNo are stored in the same bucket.

import java.util.HashSet;
class Student 
{
	int rollNo;
	String name;
	String className;
	Student(int rollNo, String name, String className)
	{
		this.rollNo = rollNo;
		this.className = className;
		this.name = name;
	}
	
	@Override
	public boolean equals(Object obj)
	{
		Student student = (Student)obj;
		return this.rollNo == student.rollNo;
	}
	
	@Override
	public int hashCode()
	{
		return rollNo;
	}
}

public class HashCodeExample
{
	public static void main(String args[])
	{
		HashSet<Student> setOfStudent = new HashSet<Student>();
		Student student = new Student(1, "Ravi", "MCA");
		Student student1 = new Student(2, "Ram", "MCA");
		Student student2 = new Student(1, "Ravi", "MCA");
		
		setOfStudent.add(student);
		setOfStudent.add(student1);
		setOfStudent.add(student2);
		
		System.out.println("Size of HashSet: "+ setOfStudent.size());
		
		
	}
}

Output: Size of HashSet: 2

Now you can see in the above example, Two object student and student2 are now considered equals and stored in the same memory bucket.

Leave a Comment