Why is String a good choice for a HashMap key?

String is immutable, its equals() and hashCode() are consistent, and it caches its hash code after the first calculation. Because its value can never change after it is used as a key, the entry always stays in the right bucket, and repeated lookups don't recompute the hash.

Key Points: • A key's hashCode must not change while it is in a map. Immutability guarantees this for String. • String computes hashCode once and stores it in a private field, so later calls are almost free. • equals() and hashCode() follow the contract: equal Strings always have equal hash codes. • A mutable key (for example a class whose field is changed after insertion) can "disappear": get() looks in a different bucket and returns null. • Other good keys: Integer, Long, enums, records with immutable fields.

Code Example:

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class StringKeyDemo {

    static class MutableKey {
        String name;
        MutableKey(String name) { this.name = name; }
        @Override public boolean equals(Object o) { return o instanceof MutableKey k && k.name.equals(name); }
        @Override public int hashCode() { return Objects.hash(name); }
    }

    public static void main(String[] args) {
        Map<String, Integer> prices = new HashMap<>();
        String key = "laptop";
        prices.put(key, 55_000);
        System.out.println("String key lookup: " + prices.get("laptop"));
        System.out.println("Hash: " + "laptop".hashCode() + " (computed once, then cached)");

        Map<MutableKey, Integer> broken = new HashMap<>();
        MutableKey mk = new MutableKey("laptop");
        broken.put(mk, 55_000);
        mk.name = "tablet";                          // key changed after insertion
        System.out.println("Mutable key lookup: " + broken.get(mk));
        System.out.println("Entry still there? size = " + broken.size());
    }
}

Output:

String key lookup: 55000 Hash: -1109985830 (computed once, then cached) Mutable key lookup: null Entry still there? size = 1

Good to Know: String.hashCode() is calculated as s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1]. Different strings can share a hash code ("Aa" and "BB" both give 2112), which is why HashMap always confirms a match with equals().

Interview Tip: A concise interview answer is:

"String is immutable, so its hash code can never change while it's in the map, and it caches the hash after computing it once, which makes repeated lookups fast. Its equals and hashCode are consistent, too. A mutable key is dangerous: if its fields change after insertion, it ends up in the wrong bucket and get() returns null."

Previous question: What are the common pitfalls of String.split() in Java?

Next question: Why is a char[] preferred over a String for storing passwords?

More Java Strings interview questions

All Java Strings questions