An LRUCache (Least Recently Used Cache) is a data structure that evicts the least recently accessed item when it reaches its capacity. This guide covers how to implement an LRUCache in Java using the new SequencedMap
(JDK 21+) and the classic LinkedHashMap
(for earlier JDKs).
Diagram: LRUCache with 5 entries. LRU = Least Recently Used, MRU = Most Recently Used.
Java 21 introduced SequencedMap
, making LRUCache implementation more intuitive and efficient.
// Java 21+ LRUCache using SequencedMap
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.SequencedMap;
public class LRUCache<K, V> {
private final int capacity;
private final SequencedMap<K, V> cache;
public LRUCache(int capacity) {
this.capacity = capacity;
this.cache = new LinkedHashMap<>();
}
public V get(K key) {
if (!cache.containsKey(key)) return null;
V value = cache.remove(key);
cache.put(key, value); // Move to end (most recently used)
return value;
}
public void put(K key, V value) {
if (cache.containsKey(key)) {
cache.remove(key);
} else if (cache.size() == capacity) {
K lruKey = cache.firstKey(); // Remove least recently used
cache.remove(lruKey);
}
cache.put(key, value);
}
}
Note: SequencedMap
provides firstKey()
and lastKey()
for easy LRU management.
Before Java 21, LinkedHashMap
was the go-to for LRUCache. Override removeEldestEntry
for automatic eviction.
// LRUCache using LinkedHashMap (JDK 8+)
import java.util.LinkedHashMap;
import java.util.Map;
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int capacity;
public LRUCache(int capacity) {
super(capacity, 0.75f, true); // accessOrder = true
this.capacity = capacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > capacity;
}
}
Pro Tip: This approach is thread-unsafe. Use Collections.synchronizedMap
or external synchronization for thread safety.
SequencedMap
(e.g., LinkedHashMap
in Java 21+) to manage insertion/access order and evict the least recently used item using firstKey()
.
LinkedHashMap
and override removeEldestEntry
to evict the eldest entry when the cache exceeds its capacity.
SequencedMap
(Java 21+) is a new interface that standardizes access to the first and last entries, making LRU logic more explicit. LinkedHashMap
is the classic way, but requires overriding methods for LRU behavior.
Collections.synchronizedMap
or ConcurrentHashMap
with additional logic for thread safety.
SequencedMap
for new projects on Java 21+ for clarity and maintainability.LinkedHashMap
is reliable and widely supported.Implementing an LRUCache in Java is straightforward with both modern and legacy approaches. Use SequencedMap
for new projects and LinkedHashMap
for older JDKs. Always consider thread safety and cache sizing for production systems.