🗃️ Collections Framework · Intermediate

HashMap, LinkedHashMap, TreeMap in Java

Key-value maps and their ordering guarantees.

🧩 The mysteryYou call map.put("x", 2) and Java hands you back a 1. Where did that 1 come from, and why would anyone want it?

The coat check

A Map is a coat check: hand over a key (your ticket), get back the value. Keys are unique. put on an existing key replaces the value and returns the old one (or null if the key was new).

Map<String, Integer> m = new HashMap<>();
m.put("x", 1);   // returns null
m.put("x", 2);   // returns 1 (old value)
m.get("x");      // 2
🔮 Predict it

Your turn

What does this print?

Map<String, Integer> m = new HashMap<>();
System.out.println(m.put("a", 1));
System.out.println(m.put("a", 5));
System.out.println(m.get("a"));
  1. null 1 5
  2. 1 5 5
  3. null null 5
Show the answer

First put finds no previous value → null. Second put replaces 1 and returns 1. The map now holds a=5.

Three map personalities

**HashMap: O(1) average, no order promise, allows one null key and null values. LinkedHashMap: remembers insertion order (or access order, for LRU caches). TreeMap: sorted keys**, O(log n).

Map<String, Integer> t = new TreeMap<>();
t.put("Zoe", 31);
t.put("Ali", 25);
System.out.println(t); // {Ali=25, Zoe=31}
🔮 Predict it

Re-inserting a key

What does this print?

Map<String, Integer> m = new LinkedHashMap<>();
m.put("x", 1);
m.put("y", 2);
m.put("x", 9);
System.out.println(m);
  1. {y=2, x=9}
  2. {x=9, y=2}
  3. {x=1, y=2, x=9}
Show the answer

Keys are unique, so put("x", 9) only replaces the value. Updating an existing key doesn't move it in a LinkedHashMap: x keeps its original first place.

Ask a TreeMap for neighbours

Sorted keys unlock navigation: firstKey(), **ceilingKey(k) (smallest key ≥ k), higherKey(k)** (smallest key > k), floorKey(k), and range views like headMap(k) and subMap(a, b).

var t = new TreeMap<String, Integer>();
t.put("Ann", 7); t.put("Cid", 4);
t.ceilingKey("B");  // "Cid"
t.higherKey("Ann"); // "Cid"
t.headMap("Cid");   // {Ann=7}
⚠️ The trap

TreeMap and null keys

HashMap happily stores one null key. A TreeMap with natural ordering rejects null keys with NullPointerException, because it has to call compareTo on them. Don't swap HashMap for TreeMap without checking for nulls.

Map<String, Integer> h = new HashMap<>();
Map<String, Integer> t = new TreeMap<>();
h.put(null, 1);  // ok
t.put(null, 1);  // NullPointerException
💼 In the real world

Maps on the job

HashMap caches and lookups by ID. LinkedHashMap keeps JSON fields or menu items in a stable order, and with access order it's the basis of a simple LRU cache. TreeMap powers "what's the next appointment after 10:30?" with ceilingKey.

Key takeaways

  1. put on an existing key replaces the value and returns the old one
  2. HashMap: O(1) average, allows one null key
  3. LinkedHashMap: insertion order (or access order for LRU caches)
  4. TreeMap: sorted keys, O(log n), no null keys with natural ordering

💡 A map is a coat check: you hand over a ticket (key) and get back exactly one coat (value).

🤯 Did you know?

LinkedHashMap has a constructor flag for access order and an overridable removeEldestEntry method. Together they give you a working LRU cache in about five lines.

Practice questions

What does this print?

Map<String, Integer> m = new TreeMap<>();
m.put("cherry", 3);
m.put("apple", 1);
m.put("banana", 2);
System.out.println(m);
  1. {cherry=3, apple=1, banana=2}
  2. {apple=1, banana=2, cherry=3}
  3. {cherry=3, banana=2, apple=1}
  4. [apple, banana, cherry]
Check your answer

{apple=1, banana=2, cherry=3}. TreeMap keeps keys in sorted (alphabetical) order, regardless of insertion order. Maps print as {key=value, ...}.

What does this print?

Map<String, Integer> m = new LinkedHashMap<>();
m.put("b", 1);
m.put("a", 2);
m.put("b", 3);
System.out.println(m);
  1. {a=2, b=3}
  2. {b=1, a=2, b=3}
  3. {b=3, a=2}
  4. {b=1, a=2}
Check your answer

{b=3, a=2}. Keys are unique, so the second put("b", 3) just replaces the value. Re-inserting an existing key doesn't move it in a LinkedHashMap's insertion order.

Next: how does HashMap find your value among a million entries without looking at them all? Meet the buckets.