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.