• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

HashMap Question

 
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All,

This is from 565 of K/B book (1.5)

Please explain why this code in #1 returns �Dog key� after change the �name� of Dog to "arthur" original name of Dog was "clover" when it put into HashMap.

import java.util.Map;
import java.util.HashMap;
class Dog{
public String name;
public Dog(String n){
name = n;
}
public boolean equals(Object obj){
if ((obj instanceof Dog) && (((Dog)obj).name==name))
return true;
else
return false;
}
public int hashCode(){
return name.length();
}
public String toString(){
return name;
}
}
class Cat{}

enum Pets{DOG,CAT,HORSE};

public class MapTest{
static public void main(String [] args){
Map<Object,Object> myMap = new HashMap<Object,Object>();
myMap.put("k1",new Dog("aiko"));
myMap.put("k2",Pets.DOG);
myMap.put(Pets.CAT,"CAT key");

Dog d1 = new Dog("clover");

Cat c1 = new Cat();

myMap.put(d1,"Dog key");
myMap.put(new Cat(),"Cat key");

System.out.println(myMap.get("k1"));
String k2 = "k2";
System.out.println(myMap.get(k2));
Pets p = Pets.CAT;
System.out.println(myMap.get(p));
System.out.println(myMap.get(d1));

d1.name="magnolia";
System.out.println(myMap.get(d1));

d1.name="clover";
System.out.println(myMap.get(d1));

d1.name="arthur";
System.out.println(myMap.get(d1));// #1


}
}
 
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's because d1 and the Dog reference in the HashMap refer
to the same object.
If you set the name of d1 to "magnolia", the result will be a
different hashCode (8).
The originally stored object cannot be retrieved from the Map,
because it was stored in the bucket matching the hashCode 6.
If you change the name to "arthur", however, the object can be retrieved,
because both hasCodes match ("arthur".length() == "clover".length()), and
so the correct bucket will be searched.

By changing the name using the d1 reference, you not only changed the name of the original Dog, but also the Dog in the Map (which are actually the same, as there is only one Object, with two references referring to it.)

If you changed line #1 to:
System.out.println(myMap.get(new Dog("clover"))); // #1
you would get "null" (which is actually not very surprising).

Hope i could help.
 
Nuwan Priyadarshana
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Alexander,

Thanks for your reply but still I am not clear about that
According to your reply, I want to clarify when get the element from HashMap it use only hashCode value without checking equality of the key? is it yes or no if its no , please explain this

When I change #1 as follows:

System.out.println(myMap.get(new Dog("arthur"))); // #1

Still it print as �Dog key�


Nuwan
 
Alexander Duenisch
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
retrieving a value from a HashMap always requires two
steps:

1.) use hashCode() to get the right bucket.
2.) use equals() to find the element in this bucket.

(see K/B book, page 566)
so the answer to your question is "no" (as both are required).

If you write
System.out.println(myMap.get(new Dog("arthur"))); // #1

you are actually creating a new instance which is equal
(according to the implementation of your equals() method)
to the one stored in the Map (both Dogs are called "arthur").
Also, both implementations of hashCode() will return 6.

So, 1.) the correct bucket will be found and
2.) the correct element will be found within that bucket.
 
Nuwan Priyadarshana
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Alexander,

Thanks for your help, I have got the idea why output display as �Dog key�

Nuwan
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic