3

Today I found this blog post which discussed usages of WeakHashMap over cache. It was intrigued by the fact that not the values, but the keys are stored as weak references, and when the reference is no more alive, the entire key-value pair is removed from the WeakHashMap. This would therefore cause the following to happen:

WeakHashMap map = new WeakHashMap();
SomeClass myReference1 = .... 
map.put(new Long(10), myReference1);
// do some stuff, but keep the myReference1 variable around!
SomeClass myReference2 = map.get(new Long(10)); // query the cache
if (myReference2 == null) {
    // this is likely to happen because the reference to the first new Long(10) object
    // might have been garbage-collected at this point
}

I am curious what scenarios then would take advantage of the WeakHashMap class?

Ivaylo Slavov
  • 8,839
  • 12
  • 65
  • 108
  • With autoboxing, you don't have to explicitly call `new Long(10)`. This will suffice: `map.get(10L);` – Matt Ball Jun 22 '11 at 16:00
  • possible duplicate of [When would you use a WeakHashMap or a WeakReference?](http://stackoverflow.com/questions/154724/when-would-you-use-a-weakhashmap-or-a-weakreference) – Matt Ball Jun 22 '11 at 16:00
  • 1
    @Matt Ball, this is not a duplicate since the question is to get some use cases for the WeakHashMap rather than compare it to other constructs. – Ivaylo Slavov Jun 22 '11 at 16:03

3 Answers3

3

When you want to attach metadata to an object for which you don't control the lifecycle. A common example is ClassLoader, though care must be taken to avoid creating a value->key reference cycle.

Brett Kail
  • 33,593
  • 2
  • 85
  • 90
  • And that object is then the key in the weak hash map I guess? – Ivaylo Slavov Jun 22 '11 at 16:00
  • +1 for the caveat. If you have value->key cycles what you need are [ephemeron pairs](http://en.wikipedia.org/wiki/Ephemeron). – Mike Samuel Jun 22 '11 at 16:00
  • Thanks for the info, now I see the purpose of the WeakHashMap. It is actually quite a clever solution to storing metadata, because since the key object is not available, it will be just a matter of time to have all associated to it metadata automatically disposed of. – Ivaylo Slavov Jun 22 '11 at 16:50
1

I ran the sample code to understand the difference between HashMap and WeakHashMap, Hope it helps

        Map hashMap= new HashMap();
        Map weakHashMap = new WeakHashMap();

        String keyHashMap = new String("keyHashMap");
        String keyWeakHashMap = new String("keyWeakHashMap");

        hashMap.put(keyHashMap, "helloHash");
        weakHashMap.put(keyWeakHashMap, "helloWeakHash");
        System.out.println("Before: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap"));

        keyHashMap = null;
        keyWeakHashMap = null;

        System.gc();  

        System.out.println("After: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap"));

The output will be:

Before: hash map value:helloHash and weak hash map value:helloWeakHash
After: hash map value:helloHash and weak hash map value:null
Anand
  • 20,708
  • 48
  • 131
  • 198
1

There are many uses, but one really important one is when you want to key something by Class. Maintaining a strong reference to Class instances can peg entire classloaders.

As an aside, Guava has a much more complete set of non-strong reference mapping constructs.

Dilum Ranatunga
  • 13,254
  • 3
  • 41
  • 52
  • Yes, a good point. Maybe I can use this myself to cache some metadata for a type that I retrieve by reflection (to avoid reprating reflection calls). – Ivaylo Slavov Jun 22 '11 at 16:54