Java WeakHashMap Tutorial with Examples

The WeakHashMap class in Java is a specialized type of Map where keys are weak references, meaning they can be automatically garbage collected when no longer referenced elsewhere.

This makes WeakHashMap useful for caching and storing temporary data that should not prevent objects from being garbage collected.

Key Features of WeakHashMap

✔ Uses weak references for keys (values remain strong references).
✔ Entries are removed automatically when keys are garbage collected.
✔ Good for caching, memory-sensitive applications, and reducing memory leaks.
✔ Not thread-safe (use Collections.synchronizedMap() for synchronization).

1. Creating and Using a WeakHashMap

A WeakHashMap works similarly to a HashMap, but the keys are weakly referenced.

Example: Basic WeakHashMap Usage

import java.util.WeakHashMap;

public class WeakHashMapExample {
    public static void main(String[] args) {
        WeakHashMap<String, String> weakMap = new WeakHashMap<>();

        // Creating keys as String objects
        String key1 = new String("A");
        String key2 = new String("B");
        String key3 = new String("C");

        // Adding key-value pairs
        weakMap.put(key1, "Apple");
        weakMap.put(key2, "Banana");
        weakMap.put(key3, "Cherry");

        System.out.println("Before Garbage Collection: " + weakMap);

        // Nullifying the strong references to keys
        key1 = null;
        key2 = null;

        // Hinting the JVM to run Garbage Collector
        System.gc();

        // Waiting a bit for GC to complete
        try { Thread.sleep(1000); } catch (InterruptedException e) { }

        System.out.println("After Garbage Collection: " + weakMap);
    }
}

Expected Output

Before Garbage Collection: {A=Apple, B=Banana, C=Cherry}
After Garbage Collection: {C=Cherry}

Explanation

  • key1 and key2 were weakly referenced and after setting them to null, the garbage collector removed them from the map.
  • key3 was still referenced, so it remained in the WeakHashMap.

2. Comparing WeakHashMap with HashMap

Unlike WeakHashMap, a HashMap holds strong references to keys, preventing them from being garbage collected.

Example: Difference Between HashMap and WeakHashMap

import java.util.HashMap;
import java.util.WeakHashMap;

public class HashMapVsWeakHashMap {
    public static void main(String[] args) {
        HashMap<String, String> hashMap = new HashMap<>();
        WeakHashMap<String, String> weakHashMap = new WeakHashMap<>();

        String key1 = new String("Key1");
        String key2 = new String("Key2");

        hashMap.put(key1, "Value1");
        weakHashMap.put(key2, "Value2");

        System.out.println("Before GC:");
        System.out.println("HashMap: " + hashMap);
        System.out.println("WeakHashMap: " + weakHashMap);

        // Nullifying references
        key1 = null;
        key2 = null;

        // Triggering Garbage Collection
        System.gc();

        // Waiting a bit
        try { Thread.sleep(1000); } catch (InterruptedException e) { }

        System.out.println("After GC:");
        System.out.println("HashMap: " + hashMap);
        System.out.println("WeakHashMap: " + weakHashMap);
    }
}

Expected Output

Before GC:
HashMap: {Key1=Value1}
WeakHashMap: {Key2=Value2}

After GC:
HashMap: {Key1=Value1}
WeakHashMap: {}

Explanation

  • In HashMap, Key1 was strongly referenced, so it was not garbage collected.
  • In WeakHashMap, Key2 was weakly referenced, so it got removed automatically.

3. When to Use WeakHashMap

✔ Caching Data: If you want objects to be automatically removed when no longer used.
✔ Reducing Memory Leaks: Helps avoid unintentional retention of objects.
✔ Temporary Metadata Storage: Suitable for short-lived objects.

Example: Using WeakHashMap for Caching

import java.util.WeakHashMap;

class ExpensiveObject {
    private String name;
    public ExpensiveObject(String name) { this.name = name; }
    public String toString() { return name; }
}

public class WeakHashMapCache {
    public static void main(String[] args) {
        WeakHashMap<ExpensiveObject, String> cache = new WeakHashMap<>();

        ExpensiveObject obj1 = new ExpensiveObject("Object1");
        ExpensiveObject obj2 = new ExpensiveObject("Object2");

        cache.put(obj1, "Cached Data 1");
        cache.put(obj2, "Cached Data 2");

        System.out.println("Before GC: " + cache);

        // Removing strong reference
        obj1 = null;

        System.gc();

        try { Thread.sleep(1000); } catch (InterruptedException e) { }

        System.out.println("After GC: " + cache);
    }
}

Expected Output

Before GC: {Object1=Cached Data 1, Object2=Cached Data 2}
After GC: {Object2=Cached Data 2}

Explanation

  • obj1 was removed from the map after GC because it was weakly referenced.
  • obj2 remained because it was still referenced.

4. WeakHashMap with Synchronization

Since WeakHashMap is not thread-safe, it can be synchronized using Collections.synchronizedMap().

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

public class SynchronizedWeakHashMap {
    public static void main(String[] args) {
        Map<String, String> syncWeakMap = Collections.synchronizedMap(new WeakHashMap<>());

        syncWeakMap.put("Key1", "Value1");
        syncWeakMap.put("Key2", "Value2");

        System.out.println(syncWeakMap);
    }
}

Explanation

  • Collections.synchronizedMap() makes WeakHashMap thread-safe for concurrent access.

5. Comparing WeakHashMap with Other Maps

Feature HashMap WeakHashMap LinkedHashMap TreeMap
Ordering No order No order Insertion order Sorted order
Null Keys ✅ Yes ✅ Yes ✅ Yes ❌ No
Memory Usage High (Strong References) Low (Weak References) Medium High (Sorted)
Automatic Removal ❌ No ✅ Yes (Garbage Collection) ❌ No ❌ No
Thread-Safe ❌ No ❌ No ❌ No ❌ No

Conclusion

  • WeakHashMap automatically removes unused keys when garbage collected.
  • Ideal for caching, temporary storage, and memory-sensitive applications.
  • Unlike HashMap, it does not prevent objects from being garbage collected.
  • Not thread-safe but can be synchronized using Collections.synchronizedMap().
  • If you need ordered keys, use LinkedHashMap, and if sorting is needed, use TreeMap.

Using WeakHashMap wisely can help optimize memory usage and reduce memory leaks, making it a useful tool in Java development.

Related posts

Java LinkedHashMap Tutorial with Examples

Java Interrupting a Thread Tutorial with Examples

Reentrant Monitors in Java tutorial with code examples