Wednesday, December 28, 2005

Reference Objects as Keys in Maps

WeakReference nor its parent Reference implement the hashCode or Equals method. The default implementation of the Object.equals is to check reference equality. So theoretically if i have an object objInstance and i create two WeakReferences out of it and add it to a hashmap it should not overwrite but add it. And it did.

String str1 = "oioioi";
HashMap map = new HashMap();
map.put(new WeakReference(str1),"one");
map.put(new WeakReference(str1),"two");

Map size at end of the above is 2.

Now comes the million $ the heck does a WeakHashMap work properly then if all keys are indeed WeakReferences as the doc specifies?

To unravel the mystery, lets dig a bit into the src of WeakHashMap.

All entries in a Map are made up of Entry objects.

class Entry<k, v> extends WeakReference<k> implements Map.Entry<k, v>

whereas the same in a HashMap looks like

class Entry<k, v> implements Map.Entry<k, v>

The Entry class in both maps implements equals and hashCode methods.

The keys in WeakHashMap (which are strong references) are objects that implement hashcode methods. Internally when storing the keys, they are stored as weak references since Entry extends WeakReference. And when we call equals/hashcode on these WeakReference Entry objects, the subclass Entry has overidden these methods to delegate the call to the actual key object.

Thus the mystery is solved. So essentially it means subclass WeakReference if you want to use it in a Map.

Subscribe to comments for this post

No comments:

Clicky Web Analytics