Hashcode in Java – hashCode() Method

Hashcode in Java – hashCode() Method | Here you will discuss what is the hashcode of an object in Java. How to generate hashCode value? What is the hashCode() method of java.lang.Object class and what it returns? How to override the hashCode() method in Java? What are the different ways to get the hashcode value of an object? Can we get the hashcode value of a primitive data type?

What is hashcode in Java?

Hashcode is an identity of an object. In Java, for every object, a unique number is generated by the JVM and it is nothing but a hashcode.

It is a 32-bit unique integer number and is used to differentiate one object from another object and also used for differentiating one group of objects from other groups of objects.

As per javadocs, the hashcode is defined as “hashcode is typically implemented by converting the internal address of the object into an integer number”.

What is the use of hashcode in Java?

In regular programming, we won’t use the hashcode of an object. JVM uses hashcode value while saving data in hashing-related data structures like HashTable, HashSet, and HashMap. Hashcode is mainly used while working with Set and Map collections for storing, retrieving, removing, and searching objects of a class in the hashtable data structure.

The main advantage of saving data based on hashcode is search, add, and remove operation becomes very easy, which is having time complexity O(1).

The time complexity of different search operations:-
1) Linear Search:- O(n)
2) Binary Search:- O(log n)
3) Hashing:- O(1)

hashCode() Method of Java Object class

To find hashcode value hashCode() method is defined in java.lang.Object class. It is a non-static, native method and its default implementation is returning the reference of the object in integer form.

The hashCode() method signature in java:-
public native int hashCode()
Return value:- Reference of the object in integer form.

Hashcode Java Example

We can retrieve the hashcode of an object by calling the hashCode() method of java.lang.Object class is as follows:-

public class Test {
   public static void main(String[] args) {
      Test t1 = new Test();
      Test t2 = new Test();
      System.out.println(t1.hashCode());
      System.out.println(t2.hashCode());
   }
}

Output:-

225534817
1878246837

These outputs are the hashcode of objects t1 and t2. These hashcodes are generated based on their references. Since both object references are different, so we got different hash codes.

Since the reference is varied from one computer to another computer so hashcode value also changed. We may get different hashcode values on the next execution of the program, and you will get different hashcode values on your computer.

Another example to demonstrate the hashCode() method,

class A {
   int x;
}

public class Test {
   public static void main(String[] args) {
      A a1 = new A();
      A a2 = new A();
      System.out.println(a1.hashCode());
      System.out.println(a2.hashCode());
   }
}

Output:-

1878246837
929338653

Override hashCode() Method in Java

We can also generate a custom hashcode of an object by using its states(values). In this case, we must override the hashCode() method in the subclass by returning the state of the object by developing some hashing algorithm.

class A {

   int x;

   A(int x){
      this.x = x;
   }

   @Override
   public int hashCode() {
      return x;
   }
}
public class Test {
   public static void main(String[] args) {
      A a1 = new A(10);
      A a2 = new A(20);
      System.out.println(a1.hashCode());
      System.out.println(a2.hashCode());
   }
}

Output:-

10
20

These outputs are the hashcode of the objects a1 and a2. Since the hashCode() method is overridden in the “A” class, therefore these hashcodes are generated based on their state or value.

Note:- Hashcode always doesn’t represent the address of the object.

If the hashCode() method is not overridden then it will be executed from java.lang.Object class and returns hashCode value based on the object reference. In that case, the hashcode value is representing the address of the object. But if the hashCode() is overridden in the class then it returns a value based on its state/data not based on its reference. Hence in this case hashcode doesn’t represent the address of the object.

Another example is to override the hashCode() method,

public class Student {
  int id;
  String name;
  String course;

  public Student(int id, String name, String course) {
    this.id = id;
    this.name = name;
    this.course = course;
  }
  
  @Override
  public int hashCode() {
    return (int) id * name.hashCode() * course.hashCode();
  }
}
public class Test {
  public static void main(String[] args) {
    Student s1 = new Student(1125, "John", "Java");
    System.out.println(s1.hashCode());
    
    Student s2 = new Student(8562, "Sophia", "Python");
    System.out.println(s2.hashCode());
  }
}

Output:-

1727255470
827442848

Different Cases with Hashcode Value while Overriding hashCode() method

1) What will be the hashcode value after changing the value of the object?

If the hashCode() method is not overridden then after changing the value of an object the hashcode value returned by the hashCode() method won’t change because it is reference-based. But if the hashCode() method is overridden then the hashcode value returned by the hashCode() method will also be changed.

class A {
   int x;
   A(int x){
      this.x = x;
   }
   @Override
   public int hashCode() {
      return x;
   }
}

public class Test {
   int x;
   Test(int x) {
     this.x = x;
   }

   public static void main(String[] args) {

      // hashCode() is not overriden in Test class
      Test t1 = new Test(10);
      System.out.println(t1.hashCode());

      t1.x = 20; // changing value
      System.out.println(t1.hashCode());

      // hashCode() is overriden in A class
      A a1 = new A(10);
      System.out.println(a1.hashCode());

      a1.x = 20; // changing value
      System.out.println(a1.hashCode());
   }
}

Output:-

225534817
225534817
10
20

2) Two objects can have the same hashcode (returned by hashCode() method)?

If the hashCode() method is not overridden then two different objects will never have the same hashcode value, because at a time two objects can’t have the same reference. But if the hashCode() method is overridden then its return value may be the same.

class A {
   int x;
   A(int x){
      this.x = x;
   }
   @Override
   public int hashCode() {
      return x;
   }
}

public class Test {
   public static void main(String[] args) {

      // hashCode() is not overriden in Test
      Test t1 = new Test();
      System.out.println(t1.hashCode());
      Test t2 = new Test();
      System.out.println(t2.hashCode());

      // hashCode() is overriden in A class
      A a1 = new A(10);
      System.out.println(a1.hashCode());
      A a2 = new A(10);
      System.out.println(a2.hashCode());
   }
}

Output:-

225534817
1878246837
10
10

Alternative Ways to Get JVM Generated hashcode value

JVM always generates a unique number for every object value and hashCode() method of java.lang.Object class is one of the ways to get this value. Every object will have a reference, so every object will have a reference-wise JVM-generated hashcode value.

When we are overriding the hashCode() method in our class then it generates a hashcode value based on state. But the object will also contain the JVM-generated hashcode value based on its reference. How can we get that hashcode value?

If we want to retrieve referenced wise hashcode, we must follow one of the below two approaches:-

1) System.identityHashCode():- It is a static native method defined in the System class to return reference-wise JVM generated hashcode of the given object. Its prototype is:- public static native int identityHashCode(Object obj)

2) super.hashCode():- By calling super.hashCode() method from a new method that is defined in the subclass.

Program to demonstrate if we don’t override hashCode() method in our class then hashCode(), System.identityHashCode(), and super.hashCode() returns the same value which is based on the reference of the object.

public class Test {

   public int JVMHashCode() {
      return super.hashCode();
   }

   public static void main(String[] args) {
      Test t1 = new Test();
      System.out.println(t1.hashCode());
      System.out.println(System.identityHashCode(t1));
      System.out.println(t1.JVMHashCode());

      Test t2 = new Test();
      System.out.println(t2.hashCode());
      System.out.println(System.identityHashCode(t2));
      System.out.println(t2.JVMHashCode());
   }
}

Output:-

225534817
225534817
225534817
1878246837
1878246837
1878246837

If we override hashCode() method then the hashCode() method return value based on state. And we can use System.identityHashCode(), or super.hashCode() method to get the JVM generated hashcode value.

class A {
   int x;
   A(int x){
      this.x = x;
   }
   @Override
   public int hashCode() {
      return x;
   }
   public int JVMHashCode() {
      return super.hashCode();
   }
}

public class Test {

   public static void main(String[] args) {
      A a1 = new A(10);
      System.out.println(a1.hashCode());
      System.out.println(System.identityHashCode(a1));
      System.out.println(a1.JVMHashCode());

      A a2 = new A(20);
      System.out.println(a2.hashCode());
      System.out.println(System.identityHashCode(a2));
      System.out.println(a2.JVMHashCode());
   }
}

Output:-

10
1878246837
1878246837
20
929338653
929338653

hashCode() vs identityHashCode()

The hashCode() method can be overridden but System.identityHashCode() can’t be overridden. The hashCode() method is a non-static method so, to call this method object should be there. The System.identityHashCode() is static method. Therefore It also can be used to get the hashcode value of the primitive variables.

public class Test {
   public static void main(String[] args) {

      int x = 10;
      System.out.println(System.identityHashCode(x));

      // System.out.print(x.hashCode()); // error
      // error: int cannot be dereferenced
   }
}

Output:-

648436640

If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do you find anything incorrect? Let us know in the comments. Thank you!

Leave a Comment

Your email address will not be published. Required fields are marked *