TreeMap and red-black trees
TreeMap internals, red-black tree balancing, comparator rules, NavigableMap APIs, and when to choose TreeMap over HashMap or LinkedHashMap.
On this page
🌳 What is TreeMap?
TreeMap is a Map that keeps its keys sorted by a red-black tree. You trade expected O(1) hash lookup for O(log n) operations, and in return you get sorted iteration plus nearest-key methods like floorKey and ceilingKey. If your stock prices are keyed as 100, 105, 112, a query for 108 can jump to 105 and 112 without scanning every price.
Think of a TreeMap as a well-organized library shelf. A HashMap is a storage room with labeled bins: great when you know the exact label. A TreeMap keeps every book in order, so you can ask for the book just before or just after the one you named.
What you’ll learn
- Describe
TreeMapas a red-black tree of entries withleft,right,parentandcolor - State the five red-black rules and the height bound **
<= 2 * log2(n + 1)** - Explain
putas BST insertion followed by rotations and recoloring infixAfterInsertion - Choose between
ComparableandComparator, and explain why comparators must be consistent with equals - Use
NavigableMapmethods:floorKey,ceilingKey,higherEntry,lowerEntry, range views anddescendingMap - Compare
TreeMap,HashMapandLinkedHashMapwith practical operation costs and ordering guarantees
For this lesson, we'll focus on TreeMap internals: red-black tree rules, Entry{key,value,left,right,parent,color}, insertion followed by fixAfterInsertion, rotations and recoloring at intuition level, Comparable versus Comparator, null-key behavior, NavigableMap APIs, and the practical TreeMap versus HashMap versus LinkedHashMap decision. Range-query patterns get their own lesson, so we'll link to Range queries with TreeMap instead of repeating that full playbook here.
Below the line (out of scope)
HashMapbuckets, collision handling and treeified bins: How HashMap works- Comparator design, chaining and overflow-safe comparisons: Comparable vs Comparator
- Full range-query recipes with
subMap, windows and intervals: Range queries with TreeMap TreeSet, which is a set backed by aTreeMap: How HashSet, LinkedHashSet and TreeSet work
The 30-second answer
TreeMap is a sorted map implemented as a red-black tree. Each entry stores key, value, left child, right child, parent and color. get, put, remove, firstEntry, floorKey, ceilingKey, headMap, tailMap and subMap are O(log n), except iterating over results is O(m). Keys are ordered by a constructor Comparator, or by their natural Comparable order if no comparator is supplied. TreeMap uses compare, not equals, to decide whether two keys are the same, so the order must be consistent with equals or the map will surprise you. Natural ordering rejects null keys with NullPointerException. Use TreeMap when sorted keys or nearest-key navigation are core to the problem; use HashMap for exact lookup when order does not matter.
Interview radar
Asked often: Why choose TreeMap over HashMap, and what is the time complexity?
Senior rounds probe: Comparator consistency with equals, live range views, null keys, and why red-black trees stay balanced enough without being perfectly balanced.
Production angle: A leaderboard keyed only by score silently overwrites players with the same score.
01Picture it first: a self-correcting family tree
A binary search tree keeps smaller keys on the left and larger keys on the right. That alone is not enough, because inserting sorted keys into a plain BST creates a linked list and turns lookup into O(n). A red-black tree adds one bit of color per node and a few repair rules so the tree never gets too tall.
The diagram shows the local move you should recognize. A rotation changes parent-child links while preserving sorted order.
A small red-black tree before and after a left rotation, with orange red nodes and ink black nodes, showing that sorted order is preserved while the heavy right side is lifted
The important idea is not memorizing every case. Rotations preserve order; recoloring preserves the black-height rules. TreeMap combines those two moves after insertions and removals.
02Red-black trees under the hood
A TreeMap entry is a node in a binary search tree. The OpenJDK class is called Entry, and conceptually it looks like this:
static final class Entry<K, V> implements Map.Entry<K, V> {
K key;
V value;
Entry<K, V> left;
Entry<K, V> right;
Entry<K, V> parent;
boolean color; // RED or BLACK
}
Every search compares the requested key with the current node's key. Smaller goes left, larger goes right, equal means this is the entry. The only question is how the tree avoids becoming a long chain.
These are the five red-black rules interviewers expect:
- Every node is either red or black.
- The root is black.
- Every missing child, often drawn as a NIL leaf, is black.
- A red node cannot have a red parent or red child.
- Every path from a node to its descendant NIL leaves has the same number of black nodes.
Those rules imply a useful bound: a red-black tree with n real nodes has height at most 2 * log2(n + 1). For 1,000,000 entries, log2(1,000,001) is about 20, so the height is at most about 40. That is why operations are O(log n), even though the tree is not perfectly balanced.
A TreeMap lookup with 1,000,000 keys takes at most about 40 key comparisons by the red-black height bound. A HashMap exact lookup is expected O(1), but gives you no sorted traversal or nearest-key navigation. If your comparator does expensive work, such as locale-aware collation on long strings, those O(log n) comparisons dominate the cost.
03Put: BST insert, then fix the colors
Insertion starts exactly like a normal binary search tree insert. Walk down using compare, attach the new node where the missing child was, and color the new node red. Red is the optimistic choice: it does not change the black count on any root-to-leaf path.
Try it yourself first
Insert 10, 20, then 30 into an empty TreeMap<Integer, String>. What shape would a plain BST have, and why is that a problem?
TreeMap<Integer, String> prices = new TreeMap<>();
prices.put(10, "low");
prices.put(20, "mid");
prices.put(30, "high");
System.out.println(prices.keySet()); // [10, 20, 30]
A plain BST would be 10 -> 20 -> 30, a right-leaning chain. A red-black tree repairs that local shape. After inserting 30, the new red node has a red parent (20), which violates rule 4. Since the uncle is black or missing, fixAfterInsertion rotates left around 10 and recolors 20 black and 10 red.
At intuition level, fixAfterInsertion repeats this loop:
- If the new node is the root, make it black and stop.
- If the parent is black, all rules are fine and stop.
- If the parent and uncle are red, recolor parent and uncle black, grandparent red, then continue from grandparent.
- If the parent is red and the uncle is black, rotate to straighten a zig-zag if needed, then rotate around the grandparent and recolor.
// Not JDK code, just the shape of the algorithm.
while (node != root && colorOf(parentOf(node)) == RED) {
if (parentOf(node) == leftOf(parentOf(parentOf(node)))) {
Entry<K, V> uncle = rightOf(parentOf(parentOf(node)));
if (colorOf(uncle) == RED) {
setColor(parentOf(node), BLACK);
setColor(uncle, BLACK);
setColor(parentOf(parentOf(node)), RED);
node = parentOf(parentOf(node));
} else {
// rotate and recolor, mirrored for the other side
}
}
}
root.color = BLACK;
Premium lesson
Keep reading with the Java Pass
The rest of this lesson is part of Java One-Stop Interview Prep: in-depth explanations, diagrams, model answers and how to say them in the interview.
- Comparable, Comparator and the equality trap
- NavigableMap: nearest keys and live views
- TreeMap vs HashMap vs LinkedHashMap
- Scenario patterns interviewers like
- How to say it in the interview
From ₹199 · one-time payment · No auto-renewal