Stage 3: Core APIs, lesson 6 of 12

Maps in practice

Intermediate3 min read@since 9Code runs on your Java 25
Explain it forThe essentials plus production detail and pitfalls.

Choosing a map:

  • HashMap: fastest, no order. The default.
  • LinkedHashMap: keeps insertion order, or access order for caches.
  • TreeMap: sorted by key, with range queries like floorKey, ceilingEntry and headMap.
  • ConcurrentHashMap: safe for many threads.
  • Map.of(…): small, fixed and unmodifiable.

Modern methods that remove boilerplate:

  • getOrDefault(key, fallback)
  • computeIfAbsent(key, k -> new ArrayList<>()) for grouping
  • merge(key, 1, Integer::sum) for counting
  • entrySet() to loop over keys and values together

LinkedHashMap can even be a tiny LRU cache: turn on access order and override removeEldestEntry.

Example

Java
Map<String, Integer> wordCount = new HashMap<>();
for (String w : "to be or not to be".split(" ")) {
    wordCount.merge(w, 1, Integer::sum);             // {to=2, be=2, or=1, not=1}
}

Map<String, List<String>> byCity = new HashMap<>();
byCity.computeIfAbsent("Pune", k -> new ArrayList<>()).add("Asha");

TreeMap<Integer, String> tiers = new TreeMap<>(Map.of(0, "Bronze", 1000, "Silver", 5000, "Gold"));
System.out.println(tiers.floorEntry(3200).getValue());   // Silver

class LruCache<K, V> extends LinkedHashMap<K, V> {
    private final int capacity;
    LruCache(int capacity) {
        super(16, 0.75f, true);                          // true = access order
        this.capacity = capacity;
    }
    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > capacity;
    }
}

for (Map.Entry<String, Integer> e : wordCount.entrySet()) {
    System.out.println(e.getKey() + " = " + e.getValue());
}

Common mistake

Using a mutable object as a key and changing it after putting it in. The entry becomes unreachable.

Under the hood

Looping over keySet() and calling get() does two lookups per entry; loop over entrySet() instead. HashMap allows one null key, while ConcurrentHashMap, Map.of and a naturally ordered TreeMap reject null keys. For a real cache with expiry and size limits, use Caffeine or Spring's cache support rather than a hand-made LRU.

Check yourself

Which method counts occurrences in one call?

How this connects

Was this lesson helpful?

Finished reading? Mark it complete to track your progress.