aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Using object as keys in maps Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Using object as keys in maps" Watch "Using object as keys in maps" New topic
Author

Using object as keys in maps

Naresh Chaurasia
Ranch Hand

Joined: May 18, 2005
Posts: 357
With reference to page no:623 (SCJP1.6 Kathy Sierra), i was trying to execute the following code.



I have following question. In the lines


If the values of d1.name is "clover", then i get value "Dog1 key". But i am creating new instance of Dog1 as key and trying to access the value from map. If the value of d1.name is not "clover", the the value returned from map is null. The value of d1.name should not determine the value returned from map, but in this example the value of d1.name determines what values is returned by map.

Please explain.


SCJP 1.4, SCWCD1.4, OCA(1Z0-007)
Seetharaman Venkatasamy
Ranch Hand

Joined: Jan 28, 2008
Posts: 5575

But i am creating new instance of Dog1 as key and trying to access the value from map


Hmm, your big program explained about importance of hashcode value in the Map datastructure.
so, System.out.println(m.get(new Dog1("clover"))); // #2 you are confused here since new instance right?

you just pass an new instance as new Dog1("revolc") and then try .

note: better to use immutable object as a key in map
Abimaran Kugathasan
Ranch Hand

Joined: Nov 04, 2009
Posts: 2066

Naresh Chaurasia wrote:
I have following question. In the lines


If the values of d1.name is "clover", then i get value "Dog1 key". But i am creating new instance of Dog1 as key and trying to access the value from map. If the value of d1.name is not "clover", the the value returned from map is null. The value of d1.name should not determine the value returned from map, but in this example the value of d1.name determines what values is returned by map.

Please explain.



When we creating the Map with the key/object pair, it uses the object's hashCode() and equals() methods to determine whether to accept the key/value pair in the map. And, it, the Map, creates hash code buckets, and have along it. When we change the hashCode of that particular key/object after we've put it into that Map, it(the Map) doesn't update this information. So when we use this object(key) to get the object pair on the Map, first the Map checks whether the invoking key object has the same hash code bucket, which the Map has. If it doesn't has that bucket, it simply tells us that, it doesn't have that object pair.

here, d1 object's hash code is 9, but, the Map don't have that bucket(with the value of 9), so it return null.

Now, the Map has this bucket, and further it checks with the equals() method, and return it's object pair.


Let see, what others opinion...


|BSc in Electronic Eng| |SCJP 6.0 91%| |SCWCD 5 92%|
Naresh Chaurasia
Ranch Hand

Joined: May 18, 2005
Posts: 357
Seetharaman ,
I ran the following code, after commenting d1.name.



I get the following output

Dog1 key
Dog1 key
Dog1 key
null

If i run the following code



I get the following outpur.

null
Dog1 key
null
null

Still not clear why it is so?
Pradeep Kr
Greenhorn

Joined: Feb 17, 2010
Posts: 22
I think Abimaran Kugathasan explained it. But I will try if that helps you.

You need to understand how HashMap works. Please read relevant K&B book section one more time, it explain in better way.
While putting key-value pair in map, HashMap uses key's hashCode() method to determine which bucket to put in this key-value pair. If your key's hashCode() keep changing depending upon some internal state of object (in this case length of name variable), HashMap is not going to rearrange it self. It will still hold key-value pair in the same old bucket.

While getting objects from Hashmap, it two step process, finding correct bucket (using hashCode() of key) and finding correct object in that bucket(using equals() method of key).

Please try to go through the question once again now. It should clear up your doubt.
Abimaran Kugathasan
Ranch Hand

Joined: Nov 04, 2009
Posts: 2066

Pradeep- Kumar wrote:I think Abimaran Kugathasan explained it. But I will try if that helps you.

You need to understand how HashMap works. Please read relevant K&B book section one more time, it explain in better way.
While putting key-value pair in map, HashMap uses key's hashCode() method to determine which bucket to put in this key-value pair. If your key's hashCode() keep changing depending upon some internal state of object (in this case length of name variable), HashMap is not going to rearrange it self. It will still hold key-value pair in the same old bucket.

While getting objects from Hashmap, it two step process, finding correct bucket (using hashCode() of key) and finding correct object in that bucket(using equals() method of key).

Please try to go through the question once again now. It should clear up your doubt.


Same Blood.
Seetharaman Venkatasamy
Ranch Hand

Joined: Jan 28, 2008
Posts: 5575

sorry for my late reply.

Naresh Chaurasia wrote:
If i run the following code



I get the following outpur.

null
Dog1 key
null
null

Still not clear why it is so?


Oops! I misread your equals method as



so, I wrongly answer in my first post. sorry, please Ignore that post. now coming back to the track,

first of all read this :http://www.javaworld.com/community/?q=node/1006



Dog1 d1 = new Dog1("clover"); // let's keep this reference
m.put(d1, "Dog1 key");

First,you stored "Dog1 key" object in key Object d1 by using hashing[hashcode=clover.length and identity=clover]


in(1) : you changed the d1 object's identity to magnolia and hashcode also change as per your hashcode method. now when you say m.get(d1), get method calculate hashcode as you override[name.length] and try to find the index[bucket], but it cant find the particular bucket[an object with identity magnolia,
hence it returns null.

in(2) : you changed the d1 object's identity to clover but hashcode remains same. now when you say m.get(d1), get method calculate hashcode as you override[name.length] and find the index[bucket], there is an object[d1 which has an identity/name clover] ,hence it returns the object(Dog1 key)

in(3) : you changed the d1 object's identity to arthur and hashcode remains same. now when you say m.get(d1), get method calculate hashcode as you override[name.length] and find the index[bucket], but it contains an d1 object with identity of clover, not object with arthur hence it returns null.


 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Using object as keys in maps