WeakHashMap vs HashMap in Java

1. Introduction

In Java, the HashMap is a widely used collection that stores key-value pairs for efficient retrieval. On the other hand, WeakHashMap is a special type of map that stores keys in a way that allows them to be garbage-collected if they are no longer referenced outside of the WeakHashMap. This makes WeakHashMap an excellent choice for caches and other memory-sensitive applications.

2. Key Points

1. HashMap retains all its keys as long as the map itself is referenced, regardless of whether the keys have other references to them.

2. WeakHashMap keys are held weakly, which means they can be garbage collected if the key objects are not referenced elsewhere.

3. The presence of a key in a WeakHashMap does not prevent its keys from being finalized and collected by the garbage collector.

4. Iteration over a HashMap can reflect the changes (like additions or removals) immediately, whereas WeakHashMap may not immediately reflect changes due to garbage collection.

3. Differences: WeakHashMap vs HashMap in Java

HashMap WeakHashMap
Stores strong references to its keys. Stores weak references to its keys.
Keys are not eligible for garbage collection as long as the map is referenced. Keys can be garbage collected if there are no other strong references to them.
Behavior of iteration is predictable and reflects the current state of the map. Iteration reflects the state of the map as of the last garbage collection.

4. Example


// Step 1: Import necessary classes
import java.util.HashMap;
import java.util.WeakHashMap;
import java.util.Map;

public class MapComparison {
    public static void main(String[] args) {
        // Step 2: Create a HashMap
        Map<String, String> hashMap = new HashMap<>();
        // Step 3: Create a WeakHashMap
        Map<String, String> weakHashMap = new WeakHashMap<>();

        // Step 4: Put key-value pairs into the HashMap
        hashMap.put(new String("key1"), "value1");
        hashMap.put(new String("key2"), "value2");

        // Step 5: Put key-value pairs into the WeakHashMap
        weakHashMap.put(new String("key1"), "value1");
        weakHashMap.put(new String("key2"), "value2");

        // Step 6: Print the size of both maps before GC
        System.out.println("Size of HashMap before GC: " + hashMap.size());
        System.out.println("Size of WeakHashMap before GC: " + weakHashMap.size());

        // Step 7: Encourage GC to run and potentially collect keys
        System.gc();

        // Step 8: Print the size of both maps after GC
        System.out.println("Size of HashMap after GC: " + hashMap.size());
        System.out.println("Size of WeakHashMap after GC: " + weakHashMap.size());
    }
}

Output:

Size of HashMap before GC: 2
Size of WeakHashMap before GC: 2
Size of HashMap after GC: 2
Size of WeakHashMap after GC: 0 (may vary depending on JVM and garbage collection)

Explanation:

1. HashMap and WeakHashMap are created and populated with key-value pairs. For WeakHashMap, keys are created as new String objects to ensure that no other references to these keys exist.

2. Before garbage collection (GC), both maps show a size of 2, indicating they contain two key-value pairs each.

3. After encouraging the GC to run, the WeakHashMap may have a reduced size if the keys were collected, while the HashMap retains its size as it holds strong references.

4. The output after GC may show that the WeakHashMap has fewer elements, demonstrating the impact of garbage collection on its keys.

5. When to use?

- Use a HashMap when you need a general-purpose map without special memory requirements.

- Opt for WeakHashMap when you require a memory-sensitive solution, such as caching, where you want the entries to be garbage collected once the keys are no longer in use elsewhere.

Comments