Java Collections – WeakHashMap Example

A WeakHashMap is a hash table based implementation of the Map interface where the keys are stored in a java.lang.ref.WeakReference. When a reference to the keys is no longer used then the entry in the map is automatically removed. In the example I have detailed when I make the references to the pinto and etzel null the entries in the WeakHashMap are automatically removed when garbage collection has occurred.

Big-O Notation

This implementation provides constant-time O(1) performance for the basic operations (get, put and containsKey) and O(h/n) for next, assuming the hash function disperses the elements properly among the buckets.

Creating a WeakHashMap

This was the old-way prior to Generics.

Map myCars = new WeakHashMap();

Generics

If you look closely, you will notice that I am using Generics to limit the type to String for the Key, and Integer for the Value in the Map. Generics add stability to your code, by having the computer detect type incompatibilities during compile-time. These runtime bugs would be more difficult to debug if left unchecked.

Map<Car,String> myCars = new WeakHashMap<Car,String>();

Adding elements

Adding elements to the myCars Map is done by using the put(Object key, Object value) method.

Removing elements

Removing elements is just a matter of calling the remove(Object key) method.

myCars.remove(camaro);
myCars.remove(taurus);

Size of Collection

Returning the number of elements in a WeakHashMap is as easy as calling the size() method.

myCars.size();

Iterating through the Collection

Java 1.5 and above provides a foreach loop, which makes it much easier to iterate over the entire collection. This is my preferred way of doing it.

// Loop through the collection of myCars
for (String name : employees.keySet()) {
   // Get the salary by passing the employee name as the key,
the salary is Auto-UnBoxed
int salary = employees.get(name); }

Worthy Note

Using a WeakHashMap for a cache is not a good implementation as it lacks a good strategy on when and how objects are removed from the cache. A good caching strategy might employ retaining those elements which have a high hit rate and remove those elements that are seldom used. Most folks refer to this as a LRU (Least Recently Used) strategy. WeakHashMap allows the JVM to remove any of the elements without allowing for any type of developer control. I would strongly recommend using a dedicated cache library like OSCache or EHCache for this purpose.

Full Program Listing (WeakHashMapExample.java)

package com.avaldes.tutorials;

import java.util.Map;
import java.util.WeakHashMap;

public class WeakHashMapExample {

  public static void main(String[] args) {
    Map<Car, String> myCars = new WeakHashMap<Car, String>();
    
    Car prius = new Car("Toyota", "Prius");
    Car pinto = new Car("Ford", "Pinto");
    Car taurus = new Car("Ford", "Taurus");
    Car maxima = new Car("Nissan", "Maxima");
    Car towncar= new Car("Lincoln", "Town Car");
    Car camaro = new Car("Chevrolet", "Carmaro");
    Car etzel = new Car("Ford", "Etzel");
    Car carrera = new Car("Porsche", "Carrera");
    Car grandprix = new Car("Pontiac", "Grand Prix");
    
    myCars.put(prius, prius.getName());
    myCars.put(pinto, pinto.getName());
    myCars.put(taurus, taurus.getName());
    myCars.put(maxima, maxima.getName());
    myCars.put(towncar, towncar.getName());
    myCars.put(camaro, camaro.getName());
    myCars.put(etzel, etzel.getName());
    myCars.put(carrera, carrera.getName());
    myCars.put(grandprix, grandprix.getName());

    System.out.println("Before removal of weak references...");
    System.gc();
    displayCars(myCars);
    System.out.println("Number of Cars: " + myCars.size());
    
    System.out.println("Removing the references to the Pinto and Etzel...");
    pinto = null;
    etzel = null;
    
    System.out.println("After removal of weak references...");
    System.gc();
    displayCars(myCars);
    System.out.println("Number of Cars: " + myCars.size());
  }
  
  public static void displayCars(Map<Car, String> map) {
    int count = 0;
    
    // Display all elements in the WeakHashMap
    for (Car c : map.keySet()) {
      count++;
      System.out.format("[%d] %s (%s)n", count, c.getName(), 
                                                c.getManufacturer());
    }
  }
}

Full Program Listing (Car.java)

package com.avaldes.tutorials;

public class Car {
  private String Manufacturer;
  private String name;
  
  public Car(String manufacturer, String name) {
    setManufacturer(manufacturer);
    setName(name);
  }

  public String getManufacturer() {
    return Manufacturer;
  }

  public void setManufacturer(String manufacturer) {
    Manufacturer = manufacturer;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

Output

Before removal of weak references...
[1] Taurus (Ford)
[2] Pinto (Ford)
[3] Carrera (Porsche)
[4] Maxima (Nissan)
[5] Carmaro (Chevrolet)
[6] Grand Prix (Pontiac)
[7] Etzel (Ford)
[8] Town Car (Lincoln)
[9] Prius (Toyota)
Number of Cars: 9

Removing the references to the Pinto and Etzel...

After removal of weak references...
[1] Taurus (Ford)
[2] Carrera (Porsche)
[3] Maxima (Nissan)
[4] Carmaro (Chevrolet)
[5] Grand Prix (Pontiac)
[6] Town Car (Lincoln)
[7] Prius (Toyota)
Number of Cars: 7

Other Related Posts

Map Examples

List Examples

Set Examples

Please Share Us on Social Media

Facebooktwittergoogle_plusredditpinterestlinkedinmail

Leave a Reply

Your email address will not be published. Required fields are marked *