Difference Between HashMap and LinkedHashMap in Java
HashMap and LinkedHashMap store key–value pairs with O(1) average operations, unique keys, one null key and any number of null values. LinkedHashMap extends HashMap and adds a doubly linked list through its entries, which gives it a predictable iteration order:
HashMap: no ordering guarantee.LinkedHashMap: insertion order by default, or access order (least recently used first), which makes it ideal for LRU caches.
1. Comparison Table
| Aspect | HashMap | LinkedHashMap |
|---|---|---|
| Iteration order | Unpredictable | Insertion order, or access order if configured |
| Internal structure | Hash table (buckets) | Hash table + doubly linked list of entries |
| Hierarchy | Extends AbstractMap | Extends HashMap; implements SequencedMap (Java 21) |
| get / put / remove | O(1) average | O(1) average, slightly more work |
| Iteration cost | Proportional to capacity + size | Proportional to size |
| Memory | Lower | Higher (before/after references per entry) |
| Eviction hook | No | removeEldestEntry() |
| Nulls | One null key, null values | One null key, null values |
| Thread-safe | No | No |
2. Insertion Order
import java.util.*;
public class MapOrder {
public static void main(String[] args) {
String[] cities = {"Pune", "Delhi", "Kochi", "Agra", "Mumbai"};
Map<String, Integer> hash = new HashMap<>();
Map<String, Integer> linked = new LinkedHashMap<>();
for (int i = 0; i < cities.length; i++) { hash.put(cities[i], i + 1); linked.put(cities[i], i + 1); }
System.out.println("HashMap : " + hash + " <- no guaranteed order");
System.out.println("LinkedHashMap : " + linked + " <- insertion order");
linked.put("Delhi", 99); // updating a key keeps its position
System.out.println("update Delhi : " + linked);
// Java 21 SequencedMap methods
LinkedHashMap<String, Integer> seq = new LinkedHashMap<>(linked);
System.out.println("firstEntry : " + seq.firstEntry() + ", lastEntry: " + seq.lastEntry());
seq.putFirst("Goa", 0);
System.out.println("putFirst(Goa) : " + seq.sequencedKeySet());
}
}
HashMap : {Delhi=2, Kochi=3, Pune=1, Agra=4, Mumbai=5} <- no guaranteed order
LinkedHashMap : {Pune=1, Delhi=2, Kochi=3, Agra=4, Mumbai=5} <- insertion order
update Delhi : {Pune=1, Delhi=99, Kochi=3, Agra=4, Mumbai=5}
firstEntry : Pune=1, lastEntry: Mumbai=5
putFirst(Goa) : [Goa, Pune, Delhi, Kochi, Agra, Mumbai]
Updating an existing key does not move it. Java 21 adds firstEntry, lastEntry, putFirst, putLast, pollFirstEntry and reversed.
3. Access Order and LRU Caches
With the constructor LinkedHashMap(capacity, loadFactor, true), every get or put moves the entry to the end. Overriding removeEldestEntry then evicts the least recently used entry automatically:
import java.util.*;
public class LruCache {
// accessOrder = true + removeEldestEntry -> a tiny LRU cache
static class Lru<K, V> extends LinkedHashMap<K, V> {
private final int capacity;
Lru(int capacity) { super(16, 0.75f, true); this.capacity = capacity; }
@Override protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { return size() > capacity; }
}
public static void main(String[] args) {
Lru<String, String> cache = new Lru<>(3);
cache.put("u1", "Asha"); cache.put("u2", "Ravi"); cache.put("u3", "Meera");
System.out.println("initial : " + cache.keySet());
cache.get("u1"); // access moves u1 to the end (most recent)
System.out.println("after get u1 : " + cache.keySet());
cache.put("u4", "Kiran"); // evicts least recently used: u2
System.out.println("after put u4 : " + cache.keySet());
}
}
initial : [u1, u2, u3] after get u1 : [u2, u3, u1] after put u4 : [u3, u1, u4]
This is enough for simple single-threaded caches; for concurrent production caches, use a library such as Caffeine.
4. When to Use Which
HashMap: the default when order does not matter.LinkedHashMap: when output order must match insertion (JSON-like data, reports, configuration), or for LRU caches.TreeMap: when keys must be sorted. See HashMap vs TreeMap.
5. Summary
- Both offer O(1) average map operations and allow one null key.
HashMaphas no defined order;LinkedHashMapkeeps insertion or access order.LinkedHashMapuses a little more memory and supports eviction withremoveEldestEntry.- Neither is thread-safe.
Related Tutorials
Frequently Asked Questions (FAQ)
Q1. What is the main difference between HashMap and LinkedHashMap?
LinkedHashMap maintains a predictable iteration order (insertion or access); HashMap does not.
Q2. Is LinkedHashMap a subclass of HashMap?
Yes. It extends HashMap and links its entries in a doubly linked list.
Q3. Which is faster?
HashMap is slightly faster for puts and removes; LinkedHashMap iterates more efficiently. Differences are small.
Q4. What is access order in LinkedHashMap?
An ordering mode, enabled by the three-argument constructor, in which entries move to the end whenever they are accessed.
Q5. How do I build an LRU cache in Java?
Extend LinkedHashMap with access order enabled and override removeEldestEntry to return true when the size exceeds the limit.
Q6. Does updating a value change insertion order?
No. Re-inserting an existing key keeps its original position in insertion-order mode.
Q7. Do both allow null keys?
Yes, one null key each, and any number of null values.
Q8. Which uses more memory?
LinkedHashMap, because each entry has two extra references.
Q9. Are they thread-safe?
No. Use ConcurrentHashMap or synchronize externally.
Q10. Is HashMap order random?
It depends on hash codes and capacity and may change after resizing, so you must not rely on it.
Q11. What is SequencedMap?
A Java 21 interface for maps with a defined encounter order. LinkedHashMap and TreeMap implement it.
Q12. Does get() modify a LinkedHashMap?
Only in access-order mode, where it moves the entry to the end. This makes iterating while calling get unsafe.
Q13. Do they have the same time complexity?
Yes, O(1) average for get, put and remove.
Q14. Are their iterators fail-fast?
Yes, both throw ConcurrentModificationException on concurrent structural changes.
Q15. How do I keep JSON field order in Java?
Use a LinkedHashMap; libraries like Jackson preserve its insertion order when serializing.
Q16. Can I sort a LinkedHashMap?
Not in place, but you can sort its entries and insert them into a new LinkedHashMap, or use a TreeMap.
Q17. What does removeEldestEntry do?
It is called after each put; returning true removes the eldest entry, which enables bounded caches.
Q18. What are the default capacity and load factor?
16 and 0.75 for both.
Q19. Which should I use for counting words in order of appearance?
LinkedHashMap with merge(word, 1, Integer::sum).
Q20. Is this asked in interviews?
Yes, often together with LRU cache design. Mention ordering modes, the linked list and removeEldestEntry.