• Post Reply Bookmark Topic Watch Topic
  • New Topic

equals and hashcode method article  RSS feed

 
sai rama krishna
Ranch Hand
Posts: 536
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I was reading below article

http://www.enterjava.com/search?updated-min=2015-01-01T00:00:00%2B05:30&updated-max=2016-01-01T00:00:00%2B05:30&max-results=6



equals and hashcode method
Why it is necessary to override equals and hashcode?

This is one of the popular interview question. So lets understand the same practically.
I have class Employee having id and name member variables and I am trying to put few Employee object as key in HashMap.
In this example I am not overriding hashcode and equals method.

Demo1Without hashcode and equals)


Possible Output 1:
{Employee [id=2, name=Tom2]=second, Employee [id=3, name=Tom3]=third, Employee [id=1, name=John1]=first, Employee [id=4, name=Tom4]=fouth}
Possible Output 2:
{Employee [id=3, name=Tom3]=third, Employee [id=4, name=Tom4]=fouth, Employee [id=2, name=Tom2]=second, Employee [id=1, name=John1]=first}


From the above output it is clear that every time you execute the code , it will generate different hashcode for your objects and they will go in different buckets.
The hashcode implementation of Object class is native









Demo 2With hashcode and Without equals)


Output:
{Employee [id=2, name=Tom2]=second, Employee [id=1, name=John1]=first, Employee [id=4, name=Tom4]=fouth, Employee [id=3, name=Tom3]=third}
As we have overriden hashcode and the calculation of hashcode value is on the basis of id and name , everytime you execute it will generate the same hashcode and it will go in the same bucket.

Now lets try to understand why we need equals method.




Demo 3With hashcode and Without equals)//demo2 also says 'Demo 2With hashcode and Without equals)' how it is different from demo 2???
Output:
{Employee [id=1, name=John1]=second, Employee [id=1, name=John1]=first}

From the above output it is clear that even though the contents of the both objects are same and hashcode is also same , they are added in same bucket. The problem here is both the objects are added. The reason is that the Object class has the equals implementation which checks the address and as these are two different objects they are different.








Now lets override equals method.

Demo 4With hashcode and equals)

Output:
{Employee [id=1, name=John1]=second}



Now you can see that only one object has been added.//why only one object addedd??

Conclusion:
It is neccessary to override equals and hashcode function for the class which is added as key in HashMap.


I have not understood how above Demo2 and Demo 3 is different and overall conclusion. Please advise
 
Campbell Ritchie
Marshal
Posts: 56599
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My, that tutorial is even worse when you see it in its full glory on the webpage than your quote from it.

I suggest you find the following three articles:
  • 1: Effective Java™ by Joshua Bloch (part of chapter 3). If you search my posts you may find a link to a free PDF sample chapter.
  • 2: Odersky Spoon and Venners, which you can find here.
  • 3: Search for “Angelika Langer Java equals hashCode”
  • Those three articles are much better than the tutorial you found, which provides next to no explanation. You can probably explain the enterjava link after reading my three resources. If you still have difficulty do come back and tell us what you don't understand.
     
    sai rama krishna
    Ranch Hand
    Posts: 536
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I am trying to digest those articles which definitely need many re-reads for me to understand.

    I got below questions on the original link i posted.



    Demo1Without hashcode and equals)


    HashMap<Employee, String> map = new HashMap<Employee, String>();
    Employee emp1 = new Employee(1, "John1");
    Employee emp2 = new Employee(2, "Tom2");
    Employee emp3 = new Employee(3, "Tom3");
    Employee emp4 = new Employee(4, "Tom4");
    map.put(emp1, "first");
    map.put(emp2, "second");
    map.put(emp3, "third");
    map.put(emp4, "fouth");
    System.out.println(map);



    Possible Output 1:
    {Employee [id=2, name=Tom2]=second, Employee [id=3, name=Tom3]=third, Employee [id=1, name=John1]=first, Employee [id=4, name=Tom4]=fouth}
    Possible Output 2:
    {Employee [id=3, name=Tom3]=third, Employee [id=4, name=Tom4]=fouth, Employee [id=2, name=Tom2]=second, Employee [id=1, name=John1]=first}

    From the above output it is clear that every time you execute the code , it will generate different hashcode for your objects and they will go in different buckets.
    The hashcode implementation of Object class is native.


    //since hashcode not implemented possible output is changing which i got it.
    //it will generate different hashcode for your objects (which objects author meant?? employee key object of the HashMap?? or value objects of HashMap like first etc String objects??) and they will go in different buckets.(what they mean by bucket??). If i take postal service analogy HashCode is like ZipCode and then equals is like door number of the house for postman to deliver the letter right. Bucket means same door number of the house??






    Demo 2With hashcode and Without equals)

    HashMap<Employee, String> map = new HashMap<Employee, String>();
    Employee emp1 = new Employee(1, "John1");
    Employee emp2 = new Employee(2, "Tom2");
    Employee emp3 = new Employee(3, "Tom3");
    Employee emp4 = new Employee(4, "Tom4");
    map.put(emp1, "first");
    map.put(emp2, "second");
    map.put(emp3, "third");
    map.put(emp4, "fouth");


    Output:
    {Employee [id=2, name=Tom2]=second, Employee [id=1, name=John1]=first, Employee [id=4, name=Tom4]=fouth, Employee [id=3, name=Tom3]=third}



    As we have overriden hashcode and the calculation of hashcode value is on the basis of id and name , everytime you execute it will generate the same hashcode(why same hashCode as id and names are different right???) and it will go in the same bucket.


    //Above Demo 2 author added 4 different employee objects as keys but what author meant by 'go in the same backet'(is it like same door number??)





    Demo 3With hashcode and Without equals)

    HashMap<Employee, String> map = new HashMap<Employee, String>();
    Employee emp1 = new Employee(1, "John1");
    Employee emp2 = new Employee(1, "John1");
    map.put(emp1, "first");
    map.put(emp2, "second");
    System.out.println(map);


    Output:
    {Employee [id=1, name=John1]=second, Employee [id=1, name=John1]=first}



    From the above output it is clear that even though the contents of the both objects are same and hashcode is also same , they are added in same bucket. The problem here is both the objects are added. The reason is that the Object class has the equals implementation which checks the address and as these are two different objects they are different.


    Here again what author meant by same hashCode so same bucket.






    Demo 4With hashcode and equals)
    HashMap<Employee, String> map = new HashMap<Employee, String>();
    Employee emp1 = new Employee(1, "John1");
    Employee emp2 = new Employee(1, "John1");
    map.put(emp1, "first");
    map.put(emp2, "second");
    System.out.println(map)



    Output:
    {Employee [id=1, name=John1]=second}



    Now you can see that only one object has been added.
    //adding one object makes sense but why i did not get like below with 'first' instead of 'second'

    //{Employee [id=1, name=John1]=first}


    i will read and understand gradually on those three links you mentioned
     
    Campbell Ritchie
    Marshal
    Posts: 56599
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    sai rama krishna wrote:I am trying to digest those articles which definitely need many re-reads for me to understand.
    The equals method is notoriously difficult.
    I got below questions on the original link i posted.
    Please don't use quote tags because they simply make the post longer and obscure the question so I might miss it altogether.

    . . .
    From the above output it is clear that every time you execute the code , it will generate different hashcode for your objects and they will go in different buckets.
    That is because you made the mistake of not overriding equals and hashCode. If you want a hash‑based collection to work, you must override both those methods correctly.
    . . . different buckets.(what they mean by bucket??).
    Start by reading about Maps in the Java™ Tutorials.
    . . . If i take postal service analogy HashCode is like ZipCode and then equals is like door number of the house for postman to deliver the letter right. Bucket means same door number of the house??
    No. I cannot think of a good real‑life analogy for hash codes.
    . . .
    From the above output it is clear that even though the contents of the both objects are same and hashcode is also same , they are added in same bucket.
    The hash code decides the bucket. If the equals method returns false, the two objects are considered different.
    . . .
    Now you can see that only one object has been added.
    //adding one object makes sense but why i did not get like below with 'first' instead of 'second'
    Does anybody say you can tell which bucket an object goes into in a Map? That is mistaken.
    . . .
    i will read and understand gradually on those three links you mentioned
    And unlike that tutorial you quoted, those links are worth reading.

    See if you can find out about putting the same “K” twice in a Map in the Java™ Tutorials link I posted earlier. That may explain why you are getting second rather than first.
     
    Campbell Ritchie
    Marshal
    Posts: 56599
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    A HashMap contains an array of Map.Entry objects, hidden from the user. Each element of the array is called a bucket, and it is possible to put several Entries in it because they can arrange themselves in a linked list. The bottom bits of a hash code are used to find the array. If you have 16 buckets you take the bottom 4 bits which range from 0b0000 to 0b1111 inclusive and that gives you indices from 0 to 15 which will exactly fill a 16‑bucket array. If that array is full you enlarge it to 32 buckets and use the bottom 5 bits of the hash code to determine the bucket.

    That means the hash code of the “K”. If that hash code changes after being used in the Map you will probably never find it again.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!