Equals and HashCode Override

Equals and HashCode Override

learninjava
Jan 11, 2015 - Java
 

Why you should override ? 

You might have seen a hundred articles on the internet on why you should override the hashcode method when you override the equals. But we are sure you might not be convinced or confused as to why you should be doing that. In the below article, we will try to explain the same in simpler terms and with our very famous angry birds example.
The reason why you should override hashcode whenever you override equals is that you need a way to create the same object you want to find. This is particularly useful when you are dealing with collections.
Finding an object is a two step process :
  • Find the bucket holding the object
  • Compare the objects in the bucket with the object we are trying to find
  • Overriding hashCode() method provides a way to find the actual bucket in which the object is present. Overriding equals() method provides a way to compare and see if the object we are finding is same or not.
     Remember!
  • You need a way to create the same object you want to find
  • hashCode() helps us to find the correct bucket
  • equals() helps us to compare the objects in the bucket
  • First, let us take a look the below example. Here, we are creating 3 AngryBird objects with different colors and adding it to a HashSet. Now, our goal is to find RED coloured bird. We will not override the hashCode() method as of now. Let us run the example and see the output,
     

    EqualsAndHashCode.java : - Without overriding hashCode 

    loading...
    Output:
    HashCode of RED bird to find : 1

    HashCodes of birds in buckets..
    Color : BLACK HashCode : 2018699554

    Color : RED HashCode : 366712642

    Color : BLUE HashCode : 1829164700

    Is RED angry bird present in the buckets ? : false

    From the output, if we do not override the hashCode() method, the RED bird to find has a different hashCode than RED bird in the HashSet. This means there is no RED angry bird in the HashSet which is wrong. Now, let us override the hashCode() and see the output. Below is the updated example,
     

    EqualsAndHashCode.java : - With overriden hashCode as zero 

    loading...
    Output:
    HashCode of RED bird to find : 0

    HashCodes of birds in buckets..
    Color : RED HashCode : 0

    Color : BLUE HashCode : 0

    Color : BLACK HashCode : 0

    Is RED angry bird present in the buckets ? : true

    Aah! After overriding the hashCode(), we now see that the hashcodes of RED angry birds matches. Also notice that now we can find the object in the HashSet.
    Are we done ? Not yet, notice that we now have the same hashcode for all the angry birds. This is not a violation or does cause any harm. If you dont know how to override hashCode(), simply return zero as shown.
    However, an efficient hashCode algorithm must distribute the objects in the buckets evenly. To understand this, we will analyse using a diagram but before that let us override the hashCode with a better algorithm. Here is how we can do one,
     

    EqualsAndHashCode.java : - With overriden and efficient hashCode 

    loading...
    Output:
    HashCode of RED bird to find : 1

    HashCodes of birds in buckets..
    Color : RED HashCode : 1

    Color : BLUE HashCode : 2

    Color : BLACK HashCode : 3

    Is RED angry bird present in the buckets ? : true

    Now since the hashCode returns the size of the bird rather than just a zero, observe that each bird has a different hash code according to their size. What is the advantage with this ?
    Let us look at the below diagram and see what happened on the heap in each of the above cases.
    https://github.com/learninjavagithub/assets/raw/master/articles/equals-and-hashcode.jpg
    The number in the square brackets is the hashcode. The bird outside the buckets is the one we want to create as a key and match it with the one in the bucket.
    When we did not override the hashCode() method, the birds are distributed into separate buckets, but there is no way to find a particular bird as the hashCodes were not equal. When the hashCode was returning zeros, all the birds were squeezed into a single bucket. When the hashCode is overriden with efficient algorithm, the birds were distributed evenly and we could also find the bird we wanted.
    Hope, after reading through this article, your search for the hashCode and equals ends... :)
    Thats all folks !! Happy coding. If you feel this helped you, keep supporting us by   or  or  below or on the articles on social media.
     
    Like us on: