TreeMap and NavigableMap
Master sorted key-value storage with TreeMap. Learn Red-Black tree fundamentals, NavigableMap operations for range queries, and real-world patterns for time-series data, autocomplete, and interval lookups.
📋 At a Glance
| Aspect | Details |
|---|---|
| Topic | TreeMap, NavigableMap, SortedMap, Red-Black Trees |
| Complexity | Intermediate to Advanced |
| Prerequisites | Part 10 (TreeSet), Part 12 (HashMap) |
| Time to Master | 3-4 hours |
| Interview Frequency | High (NavigableMap operations, tree complexity) |
🎯 What You'll Learn
After completing this article, you will be able to:
- Understand TreeMap's Red-Black tree implementation
- Use NavigableMap operations for range and proximity queries
- Implement time-series data handling with subMap
- Build autocomplete functionality with prefix matching
- Choose between TreeMap and HashMap for different use cases
Production Story: Time-Series Analytics Without a Time-Series Database
The Incident
Our analytics service needed to answer queries like "Show me all events between 10am and 2pm" with sub-millisecond response times. The initial implementation used HashMap and filtered all events:
JAVA(11 lines)CodeLoading syntax highlighter...
With 10 million events, this query took 500ms - unacceptable for real-time dashboards.
The TreeMap Solution
JAVA(23 lines)CodeLoading syntax highlighter...
- Before: O(n) = 500ms for 10M events
- After: O(log n + k) = 0.5ms for same data
- 1000x faster!
How TreeMap Makes This Possible
TEXT(23 lines)CodeLoading syntax highlighter...
Lessons Learned
- TreeMap excels at range queries - O(log n) to find boundaries
- HashMap excels at point queries - O(1) for exact key lookup
- Choose data structure based on query patterns, not just storage needs
- NavigableMap API provides powerful range operations
Mental Model: The Sorted Filing Cabinet
Think of TreeMap as a filing cabinet where folders are always in order:
TEXT(23 lines)CodeLoading syntax highlighter...
Deep Dive: TreeMap Internals
Red-Black Tree Structure
JAVA(16 lines)CodeLoading syntax highlighter...
Visual Tree Example
TEXT(17 lines)CodeLoading syntax highlighter...
TreeMap Construction
JAVA(24 lines)CodeLoading syntax highlighter...
Deep Dive: NavigableMap Operations
Entry Navigation Methods
JAVA(29 lines)CodeLoading syntax highlighter...
Submap Views
JAVA(20 lines)CodeLoading syntax highlighter...
Views Are Live!
JAVA(16 lines)CodeLoading syntax highlighter...
Descending Views
JAVA(14 lines)CodeLoading syntax highlighter...
Deep Dive: Real-World Patterns
Pattern 1: Time-Series Data
JAVA(33 lines)CodeLoading syntax highlighter...
Pattern 2: Autocomplete / Prefix Search
JAVA(32 lines)CodeLoading syntax highlighter...
Pattern 3: Interval/Range Lookup
JAVA(27 lines)CodeLoading syntax highlighter...
Pattern 4: Sliding Window
JAVA(34 lines)CodeLoading syntax highlighter...
Deep Dive: Performance Characteristics
Operation Complexity
| Operation | TreeMap | HashMap |
|---|---|---|
| get(key) | O(log n) | O(1) |
| put(key, value) | O(log n) | O(1)* |
| remove(key) | O(log n) | O(1) |
| containsKey(key) | O(log n) | O(1) |
| firstKey()/lastKey() | O(log n) | N/A |
| floorKey()/ceilingKey() | O(log n) | N/A |
| subMap() | O(log n) | N/A |
| Iteration | O(n) sorted | O(n) unsorted |
*O(1) amortized, O(n) worst case during resize
When to Use TreeMap
JAVA(23 lines)CodeLoading syntax highlighter...
When to Use HashMap
JAVA(12 lines)CodeLoading syntax highlighter...
⚠️ Common Mistakes
Mistake 1: Missing Comparable/Comparator
JAVA(21 lines)CodeLoading syntax highlighter...
Mistake 2: Inconsistent compareTo and equals
JAVA(28 lines)CodeLoading syntax highlighter...
Mistake 3: Modifying Keys After Insertion
JAVA(14 lines)CodeLoading syntax highlighter...
Mistake 4: SubMap Range Violations
JAVA(12 lines)CodeLoading syntax highlighter...
Mistake 5: Null Keys
JAVA(13 lines)CodeLoading syntax highlighter...
🐛 Debug This
Challenge 1: The Missing Entry
JAVA(8 lines)CodeLoading syntax highlighter...
Double.NaN violates comparison contract because NaN.compareTo(x) is always inconsistent (NaN is not equal to anything, including itself).The tree structure becomes corrupted. You might get wrong results or exceptions.
Challenge 2: The Overwritten Entry
JAVA(13 lines)CodeLoading syntax highlighter...
Output:
TEXT(2 lines)CodeLoading syntax highlighter...
compareTo returns 0. TreeMap considers them equal and overwrites the first entry. The id field is ignored because it's not in compareTo.Challenge 3: The Submap Surprise
JAVA(9 lines)CodeLoading syntax highlighter...
{1=v1, 2=v2, 8=v8, 9=v9, 10=v10}The submap is a live view. Clearing it removes entries 3-7 from the original map!
💻 Exercises
Exercise 1: Price Band Lookup
Implement a price band system that returns the discount for a given order amount:
JAVA(4 lines)CodeLoading syntax highlighter...
JAVA(15 lines)CodeLoading syntax highlighter...
Exercise 2: Version Range Finder
Implement a system that finds the latest compatible version:
JAVA(6 lines)CodeLoading syntax highlighter...
JAVA(24 lines)CodeLoading syntax highlighter...
Exercise 3: Rate Limiter with Time Windows
Implement a rate limiter using TreeMap:
JAVA(5 lines)CodeLoading syntax highlighter...
JAVA(40 lines)CodeLoading syntax highlighter...
Exercise 4: Calendar Event Finder
Implement a calendar that finds events overlapping with a time range:
JAVA(5 lines)CodeLoading syntax highlighter...
JAVA(29 lines)CodeLoading syntax highlighter...
Exercise 5: Nearest Neighbor Search
Implement a 1D nearest neighbor search:
JAVA(5 lines)CodeLoading syntax highlighter...
JAVA(34 lines)CodeLoading syntax highlighter...
🎤 Senior-Level Interview Questions
Question 1: TreeMap vs HashMap Performance
Choose TreeMap when:
- Range queries needed: subMap, headMap, tailMap are O(log n) in TreeMap, require O(n) scan in HashMap
- Sorted iteration: TreeMap iterates in key order naturally
- Proximity queries: floorKey, ceilingKey have no HashMap equivalent
- First/last access: firstKey, lastKey are O(log n)
JAVA(7 lines)CodeLoading syntax highlighter...
Question 2: Red-Black Tree Properties
Red-Black trees have:
- Faster insertion/deletion: Fewer rotations needed (at most 2 rotations per operation vs O(log n) for AVL)
- Slightly slower lookup: AVL is more strictly balanced
- Better for modification-heavy workloads: Java collections often modify frequently
Trade-off: Red-Black trees have height up to 2*log(n), AVL trees have height exactly log(n). This means RB lookups can be up to 2x slower in worst case, but modifications are faster.
Question 3: NavigableMap Memory Views
JAVA(16 lines)CodeLoading syntax highlighter...
Question 4: TreeMap Comparator Consistency
TreeMap uses compareTo for all key equality, ignoring equals():
JAVA(17 lines)CodeLoading syntax highlighter...
Question 5: Submap Thread Safety
TreeMap (and its views) are not thread-safe:
JAVA(17 lines)CodeLoading syntax highlighter...
Question 6: Ceiling vs Floor Use Cases
JAVA(13 lines)CodeLoading syntax highlighter...
📝 Summary & Key Takeaways
TreeMap Fundamentals
- Red-Black tree: O(log n) for all operations
- Keys must be Comparable or provide Comparator
- No null keys (usually), null values allowed
- Sorted iteration order
NavigableMap Operations
floorEntry/ceilingEntry: Closest match ≤ / ≥lowerEntry/higherEntry: Strictly < / >subMap/headMap/tailMap: Range views (live!)descendingMap: Reverse order view
Performance Trade-offs
- TreeMap: O(log n) everything, sorted, range queries
- HashMap: O(1) point operations, unsorted, no ranges
- Choose based on query patterns, not just storage
Common Patterns
- Time-series: subMap for time ranges
- Autocomplete: subMap for prefix matching
- Price bands: floorEntry for threshold lookup
- Nearest neighbor: floor + ceiling comparison
🏁 Conclusion
TreeMap is the go-to collection when you need sorted key-value storage with range query capabilities. The NavigableMap interface provides elegant solutions to problems that would require complex code with HashMap.
Key takeaways:
- TreeMap excels at range queries - O(log n) vs O(n) for HashMap
- NavigableMap operations are powerful - floor, ceiling, subMap enable elegant solutions
- Views are live - changes propagate bidirectionally
- compareTo consistency matters - TreeMap ignores equals()
- Use HashMap for point queries - when you don't need sorting or ranges
In the next article, we'll explore LinkedHashMap - the hybrid that combines HashMap's O(1) performance with predictable iteration order, plus the secret to implementing LRU caches.
📅 Review Schedule
To solidify your understanding, review this material:
- Tomorrow: Re-read NavigableMap operations section
- In 3 days: Implement Exercise 3 (Rate Limiter) again
- In 1 week: Explain TreeMap vs HashMap trade-offs to a colleague
- In 2 weeks: Review the time-series production story