Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HashMap says Key doesn't exist even though it does

Tags:

java

hashmap

I have run into an interesting problem which I'm pretty sure is the fault of HashMap. Consider the following debug code (AMap is a HashMap, key is a value passed to this method)

System.out.println("getBValues - Given: " + key);
System.out.println("getBValues - Contains Key: " + AMap.containsKey(key));
System.out.println("getBValues - Value: " + AMap.get(key));
for(Map.Entry<A,HashSet<B>> entry : AMap.entrySet()) {
    System.out.println("getBValues(key) - Equal: " + (key.equals(entry.getKey())));
    System.out.println("getBValues(key) - HashCode Equal: "+(key.hashCode() == entry.getKey().hashCode()));
    System.out.println("getBValues(key) - Key: " + entry.getKey());
    System.out.println("getBValues(key) - Value: " + entry.getValue());
}

Now in this Map I insert a single key (Channel) and value. Later I try and get the value back with get() and run this debug code which in my case gives this output:

getBValues - Given: Channel(...)
getBValues - Contains Key: false <--- Doesnt contain key?!
getBValues - Value: null   <--- Null (bad)
getBValues(key) - Equal: true <--- Given key and AMap key is equal
getBValues(key) - HashCode Equal: true
getBValues(key) - Key: Channel(Same...)
getBValues(key) - Value: []    <--- Not null (This is the expected result)

As you can see, fetching the key from the HashMap directly doesn't work but looping through I get the exact same key, meaning its there it just can't be found with get(). My question is what would cause this? How can get() not find a key that exists?

I would provide an some example code of this but I can't seem to reproduce this independently.

Any suggestions on what might be causing this?

like image 679
TheLQ Avatar asked May 14 '11 04:05

TheLQ


2 Answers

I'll bet you didn't override equals and hashCode properly in your key Channel class. That would explain it.

Joshua Bloch tells you how to do it correctly in his "Effective Java" Chapter 3.

http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf

like image 153
duffymo Avatar answered Sep 22 '22 21:09

duffymo


From what I can see, we still haven't ruled out if it has to do with immutability. If you do:

aMap.put(key, value);
key.setFieldIncludedInHashCodeAndEquals(25);

then you would get the result from above.

To rule this out, either show us more of your code or, in the for loop in your example above, add

System.out.println(aMap.get(entry.getKey()));

Also, use a debugger. That way, you can see if your object is in the correct bucket.

like image 40
Buhb Avatar answered Sep 25 '22 21:09

Buhb