HashMap, LinkedHashMap, TreeMap in Java
Key-value maps and their ordering guarantees.
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"); // 2Your 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"));null 1 51 5 5null 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}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);{y=2, x=9}{x=9, y=2}{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}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); // NullPointerExceptionMaps 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
- put on an existing key replaces the value and returns the old one
- HashMap: O(1) average, allows one null key
- LinkedHashMap: insertion order (or access order for LRU caches)
- 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).
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);- {cherry=3, apple=1, banana=2}
- {apple=1, banana=2, cherry=3}
- {cherry=3, banana=2, apple=1}
- [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);- {a=2, b=3}
- {b=1, a=2, b=3}
- {b=3, a=2}
- {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.