Criteria | WeakHashMap | HashMap |
---|---|---|
Key Storage | Uses weak references for keys | Uses strong references for keys |
Garbage Collection | When the key is no longer in ordinary use, the entry in the WeakHashMap will be removed automatically by the garbage collector | Keys and values are stored until explicitly removed or the map itself is garbage collected |
Use-case | Useful in scenarios like caches, where you don’t want the map entries to prevent the keys from being garbage collected | General-purpose map implementation, used in most scenarios where key-value pairs need to be stored |
Null Keys and Values | Allows both null keys and values, but with weak reference, a null key is equivalent to having that entry eligible for garbage collection | Allows one null key and multiple null values |
Performance | Comparatively slower due to additional overhead of handling weak references | Faster as it’s a straightforward hash table data structure |
Thread Safety | No | No |
Example: Difference Between WeakHashMap and HashMap in Java
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
public class WeakHashMapVsHashMapDemo {
public static void main(String[] args) throws InterruptedException {
// Using a WeakHashMap
Map<Object, String> weakHashMap = new WeakHashMap<>();
Object weakKey = new Object();
weakHashMap.put(weakKey, "Weak Value");
// Using a HashMap
Map<Object, String> hashMap = new HashMap<>();
Object strongKey = new Object();
hashMap.put(strongKey, "Strong Value");
// Printing values before nullifying references
System.out.println("Before nullifying references:");
System.out.println("weakHashMap value: " + weakHashMap.get(weakKey));
System.out.println("hashMap value: " + hashMap.get(strongKey));
// Nullifying the keys
weakKey = null;
strongKey = null;
// Suggesting JVM to run garbage collector
System.gc();
// Sleep to allow GC to process (for demonstration purposes)
Thread.sleep(1000);
// Printing values after suggesting GC
System.out.println("\nAfter suggesting GC:");
System.out.println("weakHashMap size: " + weakHashMap.size());
System.out.println("hashMap size: " + hashMap.size());
}
}
Output:
Before nullifying references: weakHashMap value: Weak Value hashMap value: Strong Value After suggesting GC: weakHashMap size: 0 hashMap size: 1
Explanation:
1. WeakHashMap: In a WeakHashMap, the keys are held weakly, which means if the key is not referenced outside of the WeakHashMap, it can be garbage collected. When the key is garbage collected, the associated key-value pair is removed from the map.
2. HashMap: In a HashMap, the keys are held with strong references. This means the key-value pairs remain in the map as long as the HashMap instance exists, preventing the keys from being garbage collected even if they are not referenced anywhere else.
3. In the provided example:
– We put a value associated with a key in both the WeakHashMap (weakKey) and the HashMap (strongKey).
– We then nullify both keys (weakKey and strongKey) and suggest the JVM run the garbage collector using System.gc().
– After suggesting the garbage collector to run and waiting for a short time, the size of the WeakHashMap becomes 0 because the only key it had was garbage collected. However, the HashMap size remains 1 because the strongKey, though nullified, wasn't garbage collected due to the strong reference in the HashMap.
4. WeakHashMap is particularly useful in scenarios where you want to associate temporary metadata with an object without preventing it from being garbage collected when it's no longer in use.