How would you implement an LRU cache in Java?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Least Recently Used (LRU) cache is a caching strategy that ensures that when the cache reaches its maximum capacity, the least recently accessed items are discarded first to make room for new entries. The LRU strategy provides an efficient way to manage memory and optimize performance in applications where resources are limited. In this article, we'll explore how to implement an LRU cache in Java, providing technical explanations and coding examples.
Key Concepts of LRU Cache
An LRU cache maintains the following properties:
- Capacity: The maximum number of items the cache can hold.
- Eviction Policy: The least recently used entry is removed when the cache reaches its capacity.
- Fast Access: The cache should provide fast access (ideally O(1) time complexity) for both get and put operations.
Implementation Using LinkedHashMap
Java's LinkedHashMap class provides an elegant way to implement an LRU cache by maintaining a doubly-linked list across all of its entries. Here's how it can be done:
Step-by-Step Guide
Step 1: Define the LRU Cache Class
Key Points:
- Initialization: The constructor sets up the
LinkedHashMapwith three parameters: initial capacity, load factor, and ordering mode. Specifyingtruefor ordering mode makes it access-order, turningLinkedHashMapinto an LRU cache. - Eviction Policy: Override the
removeEldestEntrymethod to specify that the eldest entry should be removed if the current size exceeds the predefined capacity.
Step 2: Demonstrate Usage
Explanation:
- Initialization: An
LRUCacheinstance is created with a capacity of 3. - Operations: We add items, access them, and continue to exceed the capacity to observe eviction of the least-recently used item.
Considerations
Performance
Utilizing LinkedHashMap, which leverages a hash table and a doubly-linked list, ensures that the operations get and put run in constant time, .
Thread Safety
Diving deeper into real-world applications, consider thread safety. For thread-safe implementations, you can wrap the LRUCache with Collections.synchronizedMap. However, for high-concurrency environments, using ConcurrentHashMap combined with custom logic might be necessary.
Memory Management
The cache should be mindful of memory consumption, particularly in memory-constrained environments. The LRU cache implicitly manages memory by evicting entries, but ensure the cache size is appropriate for the application's constraints.
Summary Table
| Feature | LinkedHashMap LRUCache |
| Time Complexity | Get/Puts: O(1) |
| Eviction Strategy | Removes least recently used item |
| Thread Safety | Non-thread-safe; synchronization needed |
| Use Case | Efficient in-memory key-value storage |
Conclusion
Implementing an LRU cache using Java's LinkedHashMap is both efficient and straightforward. By understanding the underlying mechanics of LinkedHashMap, such as ordering modes and the remove-eldest-entry policy, a proficient and effective LRU cache can be developed in Java. Additionally, for applications requiring higher concurrency, further enhancements may be warranted to ensure thread safety and optimal performance.
Related reading
- How would you program a strong read-after-write consistency in a distributed system?
- How ZooKeeper guarantees Single System Image?
- IBM MQ Multi-Instance Queues
- Idempotency and Race Condition on REST API in a Distributed System
- Huffman trees for non-binary alphabets?
- I have a Python list of the prime factors of a number. How do I pythonically find all the factors?
- Http Basic Authentication in Java using HttpClient?
- HTTP POST using JSON in Java

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.