A Java WeakHashMap class example

I ran across some Java source code today that I want to share. This code demonstrates how to use the Java WeakHashMap class, which can serve as a nice cache some times. I particularly like how this class responds to available memory and the Java garbage collection system.

Let me share the source code first, and then I'll provide a description of how it works:

/*
 * Instantiate our cache object.
 * (This line of code was really near the top of my Java class.)
 */
private Map cache = new WeakHashMap();

/**
 * This code is used to load the images used by our class.
 * If an image has already been accessed it may be cached, 
 * so look in the cache first. If it's not in the cache, 
 * load it from the disk.
 */
public ImageIcon getImage(String imageName)
{
  Object cachedItem = cache.get(imageName);
  if (cachedItem == null)
  {
    // the item wasn't found in the cache, so we'll have to
    // get it manually
    final ImageIcon imageIcon;
    try
    {
      imageIcon = new ImageIcon(CollapsePanelDemo.class.getClassLoader().getResource(imageName));
      cache.put(imageName, imageIcon);
      return imageIcon;
    }
    catch (Exception e)
    {
      throw new RuntimeException("Cannot find image. It must be on the classpath.",e);
    }
  }
  return (ImageIcon)cachedItem;
}

Discussion

Here's a brief discussion about how this Java WeakHashMap code works:

  1. Somewhere at the beginning of our class we declare and instantiate a cache object, which is really a WeakHashMap.
  2. When the getImage method is called, it will attempt to find the corresponding object in the cache map, using the imageName as the key into the map.
  3. If the object is found in the cache, the object found is returned to the calling program. If not, the object is retrieved from the disk, added to the cache, and then returned to the calling program.

WeakHashMap behavior

The cool thing about a WeakHashMap is that it is smart enough to dump its object references if the current JVM is running low on memory. That's very cool, but just as cool is that it doesn't really require any extra coding on our behalf. If for some reason you don't like this WeakHashMap behavior, you can just convert it into a HashMap, and then your images will always be cached ... at least until you run out of memory, and the JVM can't try to save you. :)

Here's a brief description of the WeakHashMap class from its javadoc:

A hashtable-based Map implementation with weak keys. An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. More precisely, the presence of a mapping for a given key will not prevent the key from being discarded by the garbage collector, that is, made finalizable, finalized, and then reclaimed. When a key has been discarded its entry is effectively removed from the map, so this class behaves somewhat differently from other Map implementations.

Here's another link to the WeakHashMap javadoc.