A WeakHashMap in Java is a pretty popular data-structure among mid to senior-level Java developers.
The WeakHashMap class is present in the java.util package. It’s a Map implementation which stores weak references to its keys. An entry in a WeakHashMap gets automatically removed when the associated key loses all of its active strong and soft references.
In this post, we’ll first talk about the types of references in Java – Soft, Weak, and Strong references. And then, we’ll learn about the WeakHashMap.
Java allows having three different types of references:
Strong references are the ones we use in our day-to-day Java programming:
Employee emp = new Employee("Jake");
Any object that is being referenced by a strong reference isn’t eligible for garbage collection.
An object pointed by a soft reference won’t be garbage collected until the JVM is in absolute need of memory. We can create a java.lang.ref.SoftReference, such as:
SoftReference<Employee> empSoft = new SoftReference<>(new Employee("Jake"));
We can create a WeakReference using java.lang.ref.WeakReference class. Any object which loses all strong and soft references will immediately become eligible for garbage collection, even when we have a few weak references pointing to it:
Employee jake = new Employee("Jake"); Employee jakeOtherStrongRef = jake; WeakReference<Employee> emp = new WeakReference<>(jake); jake = null; // object not yet eligible for GC as jakeOtherStrongRef also exists jakeOtherStrongRef = null; //object is now eligible for GC
A Java WeakHashMap is a hashing implementation which holds WeakReference for its keys. Just like a HashMap, it also supports a null key and null values. We can create a WeakHashMap using one of the available constructors:
Let’s quickly instantiate a WeakHashMap using the default constructor:
WeakHashMap<Integer, String> map = new WeakHashMap<>();
A WeakHashMap implements Map interface and so inherits all of its methods. Let’s look at the most commonly used methods:
Let’s try out a few of these methods:
map.put(1, "Argon"); map.put(2, "Nitrogen"); System.out.println(map.containsKey(1)); //true System.out.println(map.containsKey(3)); //false System.out.println(map.containsValue("Nitrogen")); //true String val = map.get(2); // "Nitrogen" int size = map.size(); //2 for(Map.Entry<Integer, String> entry : map.entrySet()) { System.out.println(entry.getKey() + ":" + entry.getValue()); }
We earlier discussed that a WeakHashMap, unlike a HashMap, stores weak references of keys.
Let’s now try to understand this concept with the help of an example.
Suppose we have an Employee class:
class Employee { private int id; private String name; //constructors, getters and setters public String toString() { return "[Employee{id=" + id + " ,name=" + name + "}]"; } }
And say we define a WeakHashMap<Employee, Integer> which stores count of dependants for each Employee:
Map<Employee, Integer> weakHashMap = new WeakHashMap<>(); Employee ray = new Employee(1, "Ray"); Employee sierra = new Employee(2, "Sierra"); weakHashMap.put(ray, 3); weakHashMap.put(sierra, 4); System.out.println(weakHashMap); //{[Employee{id=1 ,name=Ray}]=3, [Employee{id=2 ,name=Sierra}]=4} sierra = null; System.gc(); System.out.println(weakHashMap); //{[Employee{id=1 ,name=Ray}]=3}
Clearly, we can see that now our WeakHashMap no longer contains an entry for sierra. In other words, the object pointed by sierra lost its only strong reference when we set it to null and became eligible for garbage collection. On requesting garbage collection using System.gc(), the garbage collector removed that entry from the WeakHashMap.
Let’s discuss the important differences between a HashMap and a WeakHashMap:
HashMap | WeakHashMap |
---|---|
The stored entry object is not eligible for garbage collection | An entry in a WeakHashMap will be automatically removed when its key loses all strong and soft references |
HashMap holds strong references for its key objects | Weak references to keys are stored in case of a WeakHashMap |
The size() method will always return the same value unless we explicitly add or remove entries | The size() method may return smaller value as a few entries might automatically be removed by GC |
HashMap implements Cloneable interface and its clone() method returns a shallow copy of the HashMap | Doesn't implements Cloneable |
Implements Serializable interface | Doesn't supports serialization |
In this tutorial, we learned about a WeakHashMap in Java. WeakHashMap stores weak references to its key objects and so the entries may get automatically removed once the key loses all usual references.