Monday 24 March 2014

Contract between hashCode and equals

it is generally necessary to override the hashCode method whenever equals method is overridden and reversal.

Why it is necessary ?
Usually, while adding the data to the HashMaps, HashMaps use the hashCode of an object to identify the bucket. Once the bucket identified it search for the object existence in the bucket using equals method. If the object not present in the bucket, then object is added to the bucket.

Lets see it by detailed example.
import java.util.*;
public class Student {
    String name;
    int id;
    
    public boolean equals(Object obj){
        if(obj == null)
            return false;
        Student s1 = (Student) obj;
        if (this.id == s1.id)
            return true;
        return false;
    }
    
    Student(int id, String name){
        this.id = id;
        this.name = name;
    }
    
    public String toString(){
        return id +" " +name;
    }
    
    public static void main(String args[]){
        Set<Student> myDataBase = new HashSet<> ();
        
        Student s1 = new Student(1, "Krishna");
        Student s2 = new Student(2, "Anil");
        Student s3 = new Student(1, "Krishna");
        
        /* Add Data to the HashSet */
        myDataBase.add(s1);
        myDataBase.add(s2);
        myDataBase.add(s3);
        
        System.out.println(myDataBase);
        
    }
}

Output
[1 Krishna, 2 Anil, 1 Krishna]

Usually HashSet don't allow any duplicates. But as you observe the output, the student with id “1” is duplicated in the HashSet. It is because even though s1 and s2 are equal, but they produce 2 different hash codes, so there is a chance these can be presented in two different buckets. So HashSet allowed these duplicates.

To make it works fine, override the hashCode method like that two objects produce the same hashCode if those two are equal as per the equals method.

import java.util.*;
public class Student {
    String name;
    int id;
    
    public int hashCode(){
        return id;
    }
    
    public boolean equals(Object obj){
        if(obj == null)
            return false;
        Student s1 = (Student) obj;
        if (this.id == s1.id)
            return true;
        return false;
    }
    
    Student(int id, String name){
        this.id = id;
        this.name = name;
    }
    
    public String toString(){
        return id +" " +name;
    }
    
    public static void main(String args[]){
        Set<Student> myDataBase = new HashSet<> ();
        
        Student s1 = new Student(1, "Krishna");
        Student s2 = new Student(2, "Anil");
        Student s3 = new Student(1, "Krishna");
        
        /* Add Data to the HashSet */
        myDataBase.add(s1);
        myDataBase.add(s2);
        myDataBase.add(s3);
        
        System.out.println(myDataBase);
        
    }
}

Output
[1 Krishna, 2 Anil]

Prevoius                                                 Next                                                 Home

No comments:

Post a Comment