WeakHashMap and IdentityHashMap

Collections · lesson 34 of 42 · 4 min read

Two maps that change the rules: one forgets by itself, one ignores equals entirely.

Open this lesson in the learning hub

Key points

  • WeakHashMap holds keys weakly: once nothing else references a key, that entry is cleared at the next GC.
  • That makes it a cache or a metadata side table that cannot leak — but never a store you depend on.
  • A value must not reference its own key, or the entry keeps itself alive forever.
  • IdentityHashMap compares with == instead of equals, so two equal Strings are two keys.
  • It exists for object-graph bookkeeping: serializers and deep-copy code use it to mark what they already visited.
  • Both are specialist tools. If you cannot name why you need one, you want a plain HashMap.

Example

import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Map<String, String> weak = new WeakHashMap<>();
        String kept = new String("kept");
        weak.put(kept, "someone still holds this key");
        weak.put(new String("dropped"), "nothing points at that key");
        System.out.println("WeakHashMap size  : " + weak.size() + "   (both entries in)");

        System.gc();
        Thread.sleep(120);
        System.out.println("after a gc        : " + weak.size() + "   (the unreferenced key went)");
        System.out.println("kept key survives : " + weak.get(kept));

        Map<String, String> identity = new IdentityHashMap<>();
        Map<String, String> hash = new HashMap<>();
        String a = new String("key");
        String b = new String("key");
        System.out.println("a.equals(b)       : " + a.equals(b) + ",   a == b : " + (a == b));

        identity.put(a, "first");
        identity.put(b, "second");
        hash.put(a, "first");
        hash.put(b, "second");
        System.out.println("IdentityHashMap   : size " + identity.size() + "   (two keys, compared with ==)");
        System.out.println("HashMap           : size " + hash.size() + "   (one key, compared with equals)");
        System.out.println("identity.get(new) : " + identity.get(new String("key")) + "   (a fresh object is never ==)");
    }
}

WeakHashMap forgets what nobody else remembers; IdentityHashMap remembers objects, not values.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Collections course, and every lesson in it is listed on the Collections contents page.