Advanced HashMap Series: HashMap vs LinkedHashMap vs TreeMap

HarshavardhananHarshavardhanan
5 min read

In large-scale backend systems, choosing the right Map isn’t just about code correctness—it’s about cost models, access patterns, memory layouts, and downstream behavior during iteration or serialization.

This blog takes a surgical lens to dissect HashMap, LinkedHashMap, and TreeMap — not with textbook gloss, but with the precision expected when you're designing caching systems, audit pipelines, or ordered index layers in production-grade architectures.

HashMap – We Won’t Re-Explain It

Already broke this down in this post — internals, hashing, treeification, and bucket handling.

Let’s skip the theory and focus on what matters now:

Nuances & Gotchas

  • Equality Chaos: equals() and hashCode() must align perfectly. Get that wrong and you'll never find your key again.

  • Mutation Footgun: You mutate a key after putting it in? Good luck retrieving it.

  • O(n) in the shadows: All it takes is a few bad hashcodes and you fall back to linked lists — welcome to the worst-case.

  • No Iteration Guarantees: Order of entries is like Schrödinger’s cat. Don’t assume anything.

Advantages

  • Blazing fast — O(1) on average.

  • Lightweight, lean, and GC-friendly.

  • Allows one null key (yes, really).

  • Perfect for dense reads and writes where order doesn’t matter.

Disadvantages

  • Chaos in iteration.

  • Zero predictability for UI/state/order-based flows.

  • Not safe across threads — unless externally synchronized.

Real-World Use Cases

  • Caching layers under a custom eviction policy.

  • Word frequency maps, dedup sets.

  • ID → Value mappings where access speed trumps all else.


LinkedHashMap – Determinism Without Drama

What It Is

LinkedHashMap is your HashMap with memory — literally. It threads a doubly linked list through all entries to preserve insertion order or access order, depending on constructor config.

LinkedHashMap<String, String> accessOrdered = new LinkedHashMap<>(16, 0.75f, true);

That true means access-order mode. This is how LRU caches get built.

Advantages

  • Predictable iteration — no surprises.

  • Can be made LRU-like with minimal code.

  • Maintains HashMap’s average-case O(1) performance.

Disadvantages

  • Slight memory overhead from linkage nodes.

  • Not designed for huge collections with heavy churn — GC pressure can build.

  • Still not thread-safe.

Nuances & Gotchas

  • Access order only updates on get() — not on containsKey() or iteration.

  • You can override removeEldestEntry() for eviction — but be very precise or you’ll evict aggressively.

Real-World Use Cases

  • LRU Caches (your classic get() triggers reordering, oldest gets evicted).

  • Maintaining user input order (e.g., form fields).

  • Displaying data as received — configs, audit events, etc.

class LRUCache<K, V> extends LinkedHashMap<K, V> {
    private final int capacity;
    public LRUCache(int capacity) {
        super(capacity, 0.75f, true);
        this.capacity = capacity;
    }
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > capacity;
    }
}

TreeMap – When You Need Order and Range Logic

What It Is

TreeMap is built on a Red-Black Tree and keeps keys sorted, either by natural order or a custom Comparator. All operations are O(log n), but what you gain is predictability and range querying.

TreeMap<Integer, String> map = new TreeMap<>(Comparator.reverseOrder());

You get ceilingKey(), floorEntry(), subMap() — critical for slicing ordered data.

Advantages

  • Sorted key iteration by default.

  • Clean support for range queries (submaps, head/tail maps).

  • Great when keys represent a timeline, ranking, or hierarchy.

Disadvantages

  • No null keys allowed. Throws NullPointerException.

  • Higher GC load due to tree structure.

  • Slower write/read perf compared to HashMap/LinkedHashMap.

Nuances & Gotchas

  • Comparator must be consistent with equals or you'll have phantom bugs.

  • Ideal for sorted keys, not necessarily sorted values.

  • Red-Black Tree rotations can become costly under extreme insert/delete churn.

Real-World Use Cases

  • Sorted leaderboards, range-based slicing (topN, from→to segments).

  • Time-series index mapping (timestamp → metric).

  • Interval-matching configs (e.g., price slabs, scoring bands).

TreeMap<Integer, String> pricing = new TreeMap<>();
pricing.put(100, "Basic");
pricing.put(500, "Pro");
pricing.put(1000, "Enterprise");

System.out.println(pricing.ceilingEntry(600));  // 1000=Enterprise
System.out.println(pricing.floorEntry(600));    // 500=Pro

Comparison Snapshot — Read This Before You Choose

FeatureHashMapLinkedHashMapTreeMap
Key Order❌ None✅ Insertion / Access✅ Sorted
Avg put/getO(1)O(1)O(log n)
Null Keys✅ One✅ One❌ None
MemoryLeastMediumMost
Eviction Ready❌ No✅ Yes (override)❌ No
Range Query❌ No❌ No✅ Yes
Best ForSpeedOrdered IterationSorted Data

When to Use What — Architecture-Driven Decision Table

ScenarioBest FitWhy
You want raw speed, no order neededHashMapLean, fast, and gets out of your way
You need insertion/access orderLinkedHashMapMinimal upgrade from HashMap with guaranteed ordering
You need sorted keys or range queriesTreeMapRed-Black Tree ensures sort + range power
Building an LRU cacheLinkedHashMapJust set accessOrder=true, override eviction
Handling config with tiered matchingTreeMapUse floorEntry(), subMap() to match slabs
Displaying values exactly as fedLinkedHashMapKey order preserved — useful for UIs or logs

Final Byte

These three may live in the same package, but they behave like different species.

You don’t choose them based on what worked last time — you choose based on how the map will be used, scaled, iterated, and evolved.

Because in production, the wrong map doesn’t just slow you down — it rewrites the bug report you’re going to get next week.

What’s Next in the Series

Next up, we’ll dive deep into a topic that looks harmless until it starts corrupting your data structures mid-flight:

Thread Safety in HashMaps: What Breaks, Why It Breaks, and How to Design Around It

We'll explore:

  • How concurrent writes silently break HashMap

  • The difference between unsafe and deliberately safe designs

  • When to reach for ConcurrentHashMap, and when that’s not enough

  • Custom strategies: copy-on-write, segmentation, and lock-free tricks

Stay tuned…

0
Subscribe to my newsletter

Read articles from Harshavardhanan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Harshavardhanan
Harshavardhanan