Win a copy of Design for the Mind this week in the Design forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

How does the hashcode work in a map?

 
Mihai Popa
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello guys! I have some problems understanding a piece of code that uses a hashcode inside a map. So, this is the code:



And this is the result:


d1 hashcode is6
dog key
null
d1 hashcode is6
null
dog key


My hashcode is calculated (in a trivial way) using the length of the variable. But there is a problem. If i change my variable name and the new string has a different length, the hashcode doesn't work anymore. In my example, when i change the name of the variable to magnolia, the equals method doesn't find any match anymore. When i use a different name that has 6 chars the element is suddenly found (if the equals test is passed).
So... my question is: once put in a map, does the hashcode of the element remain still? Even if the variable for the that element changes (and the hashcode is calculated using that variable)?
 
Anirudh Jhinaa
Greenhorn
Posts: 8
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The hashcode is evaluated once the element is being added to the collection. This is a pitfall and one should be careful of not changing the state of the object(fields that your hashCode() and equals() depend on) once it has been added to the collections(whose underlying mechanism is based on hashing).
 
Kumaravadivel Subramani
Ranch Hand
Posts: 171
Java Linux Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As Jhinaa said it happens once the element gets added in the collection. It hold the hash code until the hashmap/collection exists, but can be modified by changing the hashCode() logic. Preferrebly generate a hash code which would not be same for different objects.
 
Winston Gutkowski
Bartender
Pie
Posts: 10254
59
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mihai Popa wrote:...My hashcode is calculated (in a trivial way) using the length of the variable. But there is a problem. If i change my variable name and the new string has a different length, the hashcode doesn't work anymore. In my example, when i change the name of the variable to magnolia, the equals method doesn't find any match anymore. When i use a different name that has 6 chars the element is suddenly found (if the equals test is passed).
So... my question is: once put in a map, does the hashcode of the element remain still? Even if the variable for the that element changes (and the hashcode is calculated using that variable)?

You actually have a couple of problems colliding at once:
1. Name length is a very bad choice for a hash, because all names with the same length will produce the same hash, which defeats the purpose of using a hashed collection.
While it is impossible to guarantee, a hash calculation should try to produce unique hashcodes for each distinct value; and while your hash calculation is legal (as is simply returning 1), it is very poor at fulfilling this requirement.

2. By changing the name of your dog, you are changing the key to your Map. This is bad for ANY Map, not just a HashMap.

You should look at the requirements for hashCode() as specified in the documentation, especially as it relates to equals().

So... my question is: once put in a map, does the hashcode of the element remain still? Even if the variable for the that element changes (and the hashcode is calculated using that variable)?

I think you may be under the impression that HashMap somehow stores your hashcode; it doesn't. It uses the hashcode to work out where the object should be put (or found). Therefore if you change your object in such a way that its hashcode changes, then the HashMap will no longer be able to find it.

Winston
 
Anirudh Jhinaa
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston has put it in better words, what I meant by hash value getting evaluated once was the fact that these values are not stored, and are used when the elements/keys are added or searched/retrieved.
 
Mihai Popa
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you all for your replies. I know the code is messy and trivial but it was intended for a better understanding on how hashcode works with collections (if a collision happens).
 
Pat Farrell
Rancher
Posts: 4678
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Following up on what the others are saying:

The fields you use to calculate the hashCode() must be immutable if you expect to ever find the record in the HashMap/HashSet.


This will not find your dog named clover. Ever.
 
Mike Simmons
Ranch Hand
Posts: 3040
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
So... my question is: once put in a map, does the hashcode of the element remain still? Even if the variable for the that element changes (and the hashcode is calculated using that variable)?

I think you may be under the impression that HashMap somehow stores your hashcode; it doesn't.

Actually, if you look at how HashMap is implemented in the JDK source code, I think you will find that it does store the hashcode internally, as part of the HashMap.Entry object it puts in the table.

Winston Gutkowski wrote:It uses the hashcode to work out where the object should be put (or found). Therefore if you change your object in such a way that its hashcode changes, then the HashMap will no longer be able to find it.

This is still true of course. Even if the correct object is (accidentally?) found using hashCode(), the HashMap will still check against == or equals(), so it's extremely possible to not find an object based on the fact that equals() may return a different value than it would have originally. Basically, changing data after it's been used in a key is a Bad Thing, and will result in Bad Things happening to the coder who does this.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic