Showing posts with label equals and hashcode. Show all posts
Showing posts with label equals and hashcode. Show all posts

Tuesday, October 8

Why should override hashcode method while overriding equals method

 Why should override hashcode method while overriding equals method

How do we compare two instances of a class in java 

Lets say there is a class 

public class Employee {

    int age;

    Employee(int age) {

        this.age = age;

    }

    public static void main(String args[]) {

        Employee emp1 = new Employee(10);
        Employee emp2 = new Employee(10);
      
        System.out.println("Are two instances equal?  :" +emp1.equals(emp2));

    }

}


On executing above program , It prints :
Are two instances equal?  :false

Why equals method says that two instances are different although they are instances of same class and have same age?

Reason : While invoking equals method first hashcode() method is executed . If hashcode() method returns different hashcode value for instances being compared equals() method is not called. Different hashcode declares that instances are different and no further comparison takes place.

So Is hashcode values for above tow instances are different ?

Lets see that 

public static void main(String args[]) {

        Employee emp1 = new Employee(10);
        Employee emp2 = new Employee(10);
       
        System.out.println("hashcode value for emp1  " + emp1.hashCode());
        System.out.println("hashcode value for emp2  "+emp2.hashCode());


    }




-->


Executing above method prints 

hashcode value for emp1  327325694
hashcode value for emp2  1657319091


 

So hashcode value returned is different for two instances . Actually hashcode() method works on its inherent algorithm to generate hashcode value of instances . Executing above program again might generate different hashcode values 

Let me execute the above program again and see what values it prints on console 

It prints 

hashcode value for emp1  1025601370
hashcode value for emp2  1578474768

 


So it has it's internal algorithm to generate hashcode value which dynamically generates the hashcode value and we have no control on that..

So how do we make equals method return true flag when comparing two instances of Employee class

let's override equals method as below 

  public  boolean equals(Object obj){
       
       return this.age==((Employee)obj).age  ;  
    }
 

Here Object class equals method is overridden . Now equals method is customized so it will declare two instances equal if their ages are equal . So emp1.equals(emp2) should return true 







But bigger barrier is hashcode() method . This method does not let the call go to equals() method . It returns false based of different hashcode value for two instances . 

So what do we do to make the call reach equals() method?

 Equals() method can be invoked only if hashcode value for two instances being compared are equal . So can we customize hashcode() method to make it happen . Let's try doing that 

     public int hashCode() {
         return this.age;
     }
 
Now executing hashcode value will print 
 
hashcode value for emp1  10
hashcode value for emp2  10

So hashcode values are equal. Hashcode method itsself can't decide in this case If 
two instance are equal and to decide that equals() method is invoked. 
 
Thus It is must to override hashcode() method to make equals() method invoked. 
 
So we can conclude 
 
If equals() method is customized and overridden then it make it work as we expect It is 
must to override hashcode method in a way to make call to equals() possible.