Learnitweb

Java WeakHashMap

The WeakHashMap class in Java is part of the java.util package and is a Map implementation that uses weak references for keys. This means that entries can be automatically removed by the garbage collector when the key is no longer in ordinary use.

It is often used for caching, memory-sensitive mappings, or metadata storage, where it is acceptable for entries to be removed when memory is needed.


1. Overview of WeakHashMap

  • Definition: WeakHashMap<K, V> is a hash table-based Map implementation that stores keys as weak references.
  • Key Characteristics:
    1. Keys are held weakly, while values are held strongly.
    2. When a key becomes weakly reachable (i.e., no strong references exist), it is eligible for garbage collection, and the corresponding entry is removed automatically.
    3. Implements the Map interface like HashMap, so most methods behave similarly.
    4. Not synchronized, so it is not thread-safe. For multi-threaded use, wrap it with Collections.synchronizedMap().
    5. Iterators are fail-fast, i.e., they throw ConcurrentModificationException if the map is modified concurrently by another thread.
  • Hierarchy:
java.lang.Object
   -> java.util.AbstractMap<K, V>
       -> java.util.WeakHashMap<K, V>

2. Internal Working

  • WeakHashMap uses WeakReference for keys.
  • Each key is wrapped in a WeakReference object.
  • When the garbage collector detects a weakly reachable key, it enqueues the reference in a reference queue, and WeakHashMap automatically removes the entry.
  • This makes WeakHashMap useful for memory-sensitive caches because it does not prevent keys from being garbage collected.

Important Note: Only the key is weakly referenced. The value remains strongly referenced as long as the entry exists.


3. Creating a WeakHashMap

You can create a WeakHashMap using constructors similar to HashMap:

3.1 Default Constructor

WeakHashMap<String, String> map = new WeakHashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
System.out.println(map); // {key1=value1, key2=value2}

3.2 Initial Capacity and Load Factor

WeakHashMap<String, String> map = new WeakHashMap<>(16, 0.75f);
  • Initial Capacity: Number of buckets in the hash table.
  • Load Factor: Threshold for resizing the hash table (default 0.75).

3.3 Copy Constructor

Map<String, String> original = new HashMap<>();
original.put("key1", "value1");

WeakHashMap<String, String> map = new WeakHashMap<>(original);
System.out.println(map); // {key1=value1}

4. Adding and Removing Elements

WeakHashMap supports standard Map operations:

WeakHashMap<String, String> map = new WeakHashMap<>();
map.put("A", "Apple");
map.put("B", "Banana");

System.out.println(map.get("A")); // Apple

map.remove("B");
System.out.println(map); // {A=Apple}

System.out.println(map.containsKey("B")); // false
System.out.println(map.containsValue("Apple")); // true

5. Iterating Over WeakHashMap

  • Iteration works like HashMap, but entries may disappear unexpectedly if keys are garbage collected.
WeakHashMap<String, String> map = new WeakHashMap<>();
map.put(new String("key1"), "value1");
map.put(new String("key2"), "value2");

for (Map.Entry<String, String> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " -> " + entry.getValue());
}
  • If the keys "key1" or "key2" no longer have strong references elsewhere, they may be removed automatically by GC, and the iteration may not include them.

6. Garbage Collection Behavior

WeakHashMap<Object, String> map = new WeakHashMap<>();
Object key = new Object();
map.put(key, "value");

System.out.println(map); // {java.lang.Object@...=value}

// Remove strong reference
key = null;

// Suggest garbage collection
System.gc();

// After some time, the entry may be removed automatically
System.out.println(map); // {}
  • Because keys are weakly referenced, once there are no strong references to the key, the map entry will eventually be removed.

7. Key Points to Remember

  1. Keys are weakly referenced, values are strongly referenced.
  2. Automatically cleans up entries whose keys are no longer referenced.
  3. Not thread-safe; wrap with Collections.synchronizedMap() for concurrency.
  4. Useful for caches, metadata, or memory-sensitive mappings.
  5. Iterators are fail-fast.
  6. Unlike HashMap, entries may disappear unpredictably if the GC runs.

8. Use Cases of WeakHashMap

  1. Memory-Sensitive Caching: Store cached data that can be automatically discarded when memory is low.
WeakHashMap<String, BufferedImage> imageCache = new WeakHashMap<>();
  1. Metadata Storage: Associate metadata with objects without preventing their garbage collection.
WeakHashMap<Object, String> meta = new WeakHashMap<>();
meta.put(new Object(), "metadata");
  1. Listener Registrations: Maintain mappings of objects to listeners without preventing the objects from being GC’ed.

9. Comparison with Other Maps

FeatureHashMapWeakHashMap
Key ReferencesStrongWeak
Null Key AllowedYesYes
Automatic CleanupNoYes (GC removes entries)
Thread SafetyNoNo (wrap to synchronize)
PerformanceO(1) operationsO(1) operations

10. Summary

WeakHashMap is a special-purpose Map in Java optimized for memory-sensitive scenarios:

  • Keys are weakly referenced, allowing GC to remove entries automatically.
  • Values are strongly referenced.
  • Useful for caches, metadata storage, and listener management.
  • Not synchronized; thread-safety must be managed externally.
  • Operations like put, get, remove are similar to HashMap.
  • Entries may disappear unpredictably when keys are no longer strongly referenced.