wood burning stoves 2.0*
The moose likes Java in General and the fly likes Problem with HashMap Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Problem with HashMap" Watch "Problem with HashMap" New topic
Author

Problem with HashMap

venkatesh babu
Greenhorn

Joined: Apr 17, 2008
Posts: 4
I know that HashMap can't hold duplicate key. see this sample code and output and tell me why it is accepting duplicate key TestMap1 objects.

package com.scjp.test;

import java.util.HashMap;

public class TestMap1 {

private int x;
TestMap1(){

}
TestMap1(int x){
this.x = x;
}
@Override
public boolean equals(Object obj) {
if(((TestMap1)obj).x == this.x)
return true;
else
return false;
}

/**
* @param args
*/
public static void main(String[] args) {
System.out.println("can a hashmap hold two objects created newly as keys ?");
HashMap map = new HashMap();
map.put(new TestMap1(), new Integer(3));
map.put(new TestMap1(), new Integer(4));
System.out.println("Size after insertion : "+ map.size());
map.put(new Integer(3),new TestMap1(3));
map.put(new Integer(3),new TestMap1(4));
System.out.println("Size after insertion : "+ map.size());
System.out.println("map.get(new TestMap() : "+ map.get(new TestMap()));
}

}

output
======

can a hashmap hold two objects created newly as keys ?
Size after insertion : 2
Size after insertion : 3
map.get(new TestMap() : null




By<br />Vbabu
yogesh totare
Greenhorn

Joined: Feb 02, 2005
Posts: 15
Try with this.

System.out.println("map.get(new TestMap() : "+ map.get(new TestMap1()));
venkatesh babu
Greenhorn

Joined: Apr 17, 2008
Posts: 4
thanks for your reply.

my problem is not that, why the following lines of code inserting 2 map entries? since we should have only unique keys.

map.put(new TestMap1(), new Integer(3));
map.put(new TestMap1(), new Integer(4));

but, the following inserts only 1 map entry

map.put(new Integer(3),new TestMap1(3));
map.put(new Integer(3),new TestMap1(4));
Usha Seetharaman
Greenhorn

Joined: Apr 08, 2008
Posts: 15
Hashmap expects a unique key. In your example its an object which is represented by its hashCode. If you add the following lines of code:

Iterator iter = map.keySet().iterator();
while(iter.hasNext()){
System.out.println("iter : "+ iter.next().hashCode());
}

There would be 2 different hashcodes that would get printed since every new object created would have a different hashcode.

In Integer class, the hashcode method is overridden to return the value passed in the constructor so new Integer(4) and new Integer(4), returns the same hashcode.

In your class TestMap1 if you add
public int hashCode()
{
return x;
}

Only one key would get added.
venkatesh babu
Greenhorn

Joined: Apr 17, 2008
Posts: 4
thanks usha, it solved my problem.
Dinesh Tahiliani
Ranch Hand

Joined: Aug 06, 2007
Posts: 486
When i complied i get,

can a hashmap hold two objects created newly as keys ?
iter : 26022015
iter : 24052850
Size after insertion : 2
Size after insertion : 4
map.get(new TestMap() : null

Why getting null . Can someone tell me?

also when i try to print the below:
System.out.println(map.containsKey(new TestHashMap1()));

System.out.println(map.containsValue(new Integer(3)));

op/ - false
true

Not bale to really get wht is happenning. Please help out...
[ April 18, 2008: Message edited by: Dinesh Tahiliani ]

Thanks<br />Dinesh
Dinesh Tahiliani
Ranch Hand

Joined: Aug 06, 2007
Posts: 486
the get returns null if key maps to nothing.
venkatesh babu
Greenhorn

Joined: Apr 17, 2008
Posts: 4
The problem which i posted is due to hashCode.
When a object of TestMap1 is created using new keyword, each time it refers it super class i.e, Object, so from the Super Class Object, it prints the hashCode while we use the following code snippet

Iterator iter = map.keySet().iterator();
while(iter.hasNext()){
System.out.println("iter : "+ iter.next().hashCode());
}

When you check with

System.out.println("map.get(new TestMap()1 : "+ map.get(new TestMap1()));
it is again creating another hashcode of Super Class Object. it will differnt now, because of differnt hashcode map doesn't find any object, so it returns a null.

To avoid all these problems, we need to implement hashCode method in the TestMap1 class like follows

public int hashCode()
{
return x;
}

I hope this will solve your problem. by doing this, the hashCode will always been dependent on the class TestMap1. So, when you create a new TestMap1() with default constructor, it will always returns a hashCode of 0 and you will get values from map.get(new TestMap1())

for your information, the full code is follows as

package com.scjp.test;

import java.util.HashMap;
import java.util.Iterator;

public class TestMap1{
private int x;
TestMap1(){
}
TestMap1(int x){
this.x = x;
}
@Override
public boolean equals(Object obj) {
if(((TestMap1)obj).x == this.x)
return true;
else
return false;
}
public int hashCode()
{
return x;
}

/**
* @param args
*/
public static void main(String[] args) {
System.out.println("can a hashmap hold two objects created newly as keys ?");
HashMap map = new HashMap();
map.put(new TestMap1(), new Integer(3));
map.put(new TestMap1(), new Integer(4));
Iterator iter = map.keySet().iterator();
while(iter.hasNext()){
System.out.println("iter : "+ iter.next().hashCode());
}
System.out.println("Size after insertion : "+ map.size());
map.put(new Integer(3),new TestMap1(3));
map.put(new Integer(3),new TestMap1(4));
System.out.println("Size after insertion : "+ map.size());
System.out.println("map.get(new TestMap()1 : "+ map.get(new TestMap1()));
}

}
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Problem with HashMap
 
Similar Threads
Find two repeating elements in an Array
Maps
hashCode and equals implementation
query regarding null key in hashmap
about clone