Sunday 19 August 2018

Why to override hasCode() and equals() together ?


Lets say your class:

Public Employee {

int empId;

Override only equals()

public boolean equals(Employee other) {

if(this.empId == other.empId) { return true}
else { return false;}

}

You will not face any issues, while using your class , till you start storing your class's object in to any hash implemented collection like HashMap,HashSet etc.


Lets say you want to store you Employee objects in to HashMap.

First lets understand, how HasMap stores the data in it.



Its a Linked List of Linked List
All indexes 0-15 are like linked buckets, then in side each bucket there is another linked list of Map.Entry, for all collision Object with same Bucket Id.


Quick logic of HashMap.put(Key,value)

1.  It first invokes the Key.HashCode() --> say 2001
2. Then tries to find the BucketId/IndexId where it has to place this object --> say divide by n  = 2
3. If next put also result in same bucketId, then that new node will be added to next node of that bucket, line above picture, key4 and key5


Coming back to question again.

Lets your class has only overridden the equals, then each time "new Employee(10)" will produce new Hashcode(Object native memory address , integer representation).

and when you do hashMap.get(new Employee(10), you will never find your object in the map, even though you had added it.

Hence you should provide you unique was of generating hashcode for your class,


Question -2

if you override only HashCode() but not equals

Then suppose your --> new Employee(10) and new Employee(11) goes in to same bucket, then, when you do hasMap.get(new Employee(10)), it will find the bucket, but in the bucket how would find exact object,

becaue inside the bucket each node's "searchedKey.equals(BucketNextkey)" will be invoked, and default implementation of Object's class equal is ==, it check if reference is same,

hence you will never find your Object inside map,even if you has put it.




No comments:

Post a Comment