LRU Cache with LinkedHashMap
Fast recall
Quick revision
Core answer
LinkedHashMap with accessOrder=true and override removeEldestEntry() to evict when size() exceeds the limit. This demonstrates the policy, but it is not a complete production cache: it is not thread-safe and has no expiry, loading, statistics, or weighted eviction.Understanding of LinkedHashMap's access-order feature and practical application of inheritance to customize collection behavior
Not knowing LinkedHashMap has a three-parameter constructor with accessOrder boolean, or trying to implement LRU from scratch without using this feature
Show the actual concise implementation—it's only a few lines and demonstrates you know this classic Java interview pattern
Interview-ready guide
Interview answer
A simple LRU policy can use LinkedHashMap in access-order mode. I call the three-argument constructor with true, then override removeEldestEntry to return true when the size exceeds the limit. Defined access operations move an entry to the end, so the first entry is the least recently used and is evicted after a new mapping pushes the map over capacity.
I describe this as a small single-threaded bounded map, not a complete cache. It needs external coordination for concurrency and does not provide expiry, loading, weighted eviction, or statistics. For production caching I would normally use a cache library when those requirements exist.
LRU Cache with LinkedHashMap
Direct Answer
For a small, single-threaded bounded LRU map, create a LinkedHashMap with accessOrder=true and override removeEldestEntry() to evict when size() exceeds the limit. This demonstrates the policy, but it is not a complete production cache: it is not thread-safe and has no expiry, loading, statistics, or weighted eviction.
Code Example
Extend LinkedHashMap, pass accessOrder=true to the constructor, and override removeEldestEntry to evict once you exceed capacity.
import java.util.LinkedHashMap;
import java.util.Map;
class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int capacity;
public LRUCache(int capacity) {
super(capacity, 0.75f, true); // accessOrder=true is the key line
this.capacity = capacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > capacity; // evict when over capacity
}
}
var cache = new LRUCache<String, String>(3);
cache.put("user:1", "Alice");
cache.put("user:2", "Bob");
cache.put("user:3", "Charlie");
cache.get("user:1"); // moves user:1 to the end (most recent)
cache.put("user:4", "Diana"); // evicts user:2 (least recent)
System.out.println(cache.containsKey("user:2")); // false
That's the whole cache — three setup lines and a one-line override do all the eviction work.
Common Mistakes & Pitfalls
- Forgetting the accessOrder parameter: the two-arg constructor
new LinkedHashMap(capacity, loadFactor)gives insertion order, sogetwon't reorder and your LRU silently behaves like FIFO. - Not overriding removeEldestEntry: the default always returns
false, so nothing is ever evicted. - Ignoring thread safety: concurrent
putorgetcan corrupt the internal linked list, causingConcurrentModificationExceptionor worse. - Misreading 'eldest': the eldest entry is the head of the access order (least recently accessed), not the one with the oldest value.
Check your understanding
Answer these without looking back at the article.
- What does access-order mode mean in LinkedHashMap?
- How would you make an LRU cache thread-safe?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.