Java中如何利用泛型写一个LRU缓存?

兄弟们有没有人讲详细点的我想问一下,Java中如何利用泛型写一个LRU缓存?
最新回答
心比柠檬酸

2026-10-19 15:14:02

在Java中,利用泛型实现LRU缓存可以通过继承LinkedHashMap并重写其removeEldestEntry方法来实现。以下是详细实现步骤和代码解析:

核心实现代码import java.util.LinkedHashMap;import java.util.Map;public class LRUCache<K, V> { private final int capacity; private final LinkedHashMap<K, V> cache; public LRUCache(int capacity) { this.capacity = capacity; this.cache = new LinkedHashMap<K, V>(capacity, 0.75f, true) { @Override protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { return size() > capacity; // 当缓存大小超过容量时移除最老元素 } }; } public V get(K key) { return cache.getOrDefault(key, null); // 获取键对应的值,不存在则返回null } public void put(K key, V value) { cache.put(key, value); // 添加或更新键值对 } public void display() { cache.forEach((k, v) -> System.out.print("(" + k + ":" + v + ") ")); System.out.println(); } public static void main(String[] args) { LRUCache<String, Integer> cache = new LRUCache<>(3); cache.put("one", 1); cache.put("two", 2); cache.put("three", 3); cache.display(); // 输出: (one:1) (two:2) (three:3) cache.get("one"); // 访问"one",使其成为最近使用的 cache.display(); // 输出: (two:2) (three:3) (one:1) cache.put("four", 4); // 添加新元素,触发移除最久未使用的"two" cache.display(); // 输出: (three:3) (one:1) (four:4) }}关键点解析
  1. 泛型设计

    类定义LRUCache<K, V>使用泛型参数K(键类型)和V(值类型),支持任意数据类型。

  2. LinkedHashMap的核心作用

    访问顺序维护:通过构造函数参数accessOrder=true,使LinkedHashMap按访问顺序排序(最近访问的元素移到链表尾部)。

    容量控制:重写removeEldestEntry方法,在插入新元素后检查缓存大小,若超过容量则自动移除链表头部的最久未使用元素。

  3. 方法功能

    get(K key):获取键对应的值,同时将该键值对标记为最近访问。

    put(K key, V value):插入或更新键值对,触发LRU淘汰机制(若缓存已满)。

    display():辅助方法,打印当前缓存内容(按访问顺序)。

  4. 示例演示

    初始化容量为3的缓存,依次插入("one",1)、("two",2)、("three",3)。

    访问"one"后,其顺序调整到末尾。

    插入("four",4)时,最久未使用的"two"被自动移除。

实现原理图示

  • 插入/访问操作:元素被移到双向链表尾部(红色箭头)。
  • 淘汰操作:当容量超限时,移除链表头部的元素(绿色箭头)。
扩展与优化建议
  1. 线程安全若需多线程支持,可用Collections.synchronizedMap包装或改用ConcurrentHashMap+手动维护访问顺序。

  2. 性能监控添加命中率统计(如hitCount和missCount)以评估缓存效率。

  3. 时间淘汰结合expireTime字段,可扩展为支持过期时间的LRU缓存。

通过泛型和LinkedHashMap的组合,此实现简洁高效地满足了LRU缓存的核心需求,同时保持了良好的扩展性。