目录

LRU缓存

目录

LRU缓存

LRU 缓存

LRU 缓存算法是 Least Recently Used 的缩写,即最近最少使用。广泛应用于需要高效管理有限缓存空间 并优化数据访问速度的场景。 主要核心逻辑,确定有限空间,插入元素在队列前部,插入时不能超过最大空间。 package lru; import java.util.HashMap; public class LRUCache { // Node 双向链表 private class Node { // 键 private K key; // 值 private V value; // 前置节点 private Node prev; // 后置节点 private Node next; public Node(K key, V value) { this.key = key; this.value = value; } public Node(){} } // 最大缓存数量 private final Integer maxSize; // 头节点 private final Node head; // 尾节点 private final Node tail; // Hash private final HashMap map; // 构造方法 public LRUCache(int maxSize) { if (maxSize <= 0) { throw new IllegalArgumentException(“Cache size must be positive”); } this.maxSize = maxSize; head = new Node(); tail = new Node(); head.next = tail; tail.prev = head; map = new HashMap(); } // 获取键值 public V get(K key) { Node node = map.get(key); if (node == null) { return null; } // 移动到头节点 nodeToHead(node); return node.value; } // 添加元素 public void put(K key, V value) { Node node = map.get(key); if (node != null) { node.value = value; nodeToHead(node); } else { node = new Node(key, value); if (map.size() >= maxSize) { map.remove(tail.prev.key); removeNode(tail.prev); } map.put(key, node); addHeadNode(node); } } // 节点前置 private void nodeToHead(Node node) { // 删除这个节点 removeNode(node); // 加入到头节点 addHeadNode(node); } // 添加头节点 private void addHeadNode(Node node) { node.next = head.next; node.prev = head; head.next.prev = node; head.next = node; } // 删除节点 private void removeNode(Node node) { node.prev.next = node.next; node.next.prev = node.prev; } // 打印 private void print() { Node item = head.next; while (item.next != null) { System.out.println(item.key + " : " + item.value.toString()); item = item.next; } } public static void main(String[] args) { LRUCache cache = new LRUCache<>(3); cache.put(1, “aaa”); cache.put(2, “bbb”); cache.put(3, “ccc”); System.out.println(cache.get(1)); System.out.println(cache.get(2)); cache.put(4, “ddd”); cache.print(); } } 在Java中,可以使用LinkedHashMap来实现LRU缓存。LinkedHashMap是一个哈希表和链表的数据结构。 package lru; import java.util.LinkedHashMap; import java.util.Map; public class LRUMap extends LinkedHashMap { // 防止被修改 private final int maxSize; // 构造方法:初始化 maxSize 和 LinkedHashMap 参数 public LRUMap(int maxSize) { super(maxSize, 0.75f, true); this.maxSize = maxSize; } // 重写移除最老条目条件 @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > maxSize; } public static void main(String[] args) { LRUMap cache = new LRUMap(3); cache.put(1, “aaa”); cache.put(2, “bbb”); cache.put(3, “ccc”); System.out.println(cache.get(1)); System.out.println(cache.get(2)); cache.put(4, “ddd”); System.out.println(“cache = " + cache); } } LinkedHashMap 部分源码: // 构造方法 // initialCapacity 初始容量,指定哈希表(Entry[] table)的初始桶数量 // loadFactor 负载因子,主要作用 决定哈希表何时触发扩容 // accessOrder 控制键值对的迭代顺序 // true 表示按照访问顺序迭代键值对 // false:插入顺序。条目按插入顺序排列,不受访问操作影响 public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor); this.accessOrder = accessOrder; } // removeEldestEntry 方法是 LinkedHashMap 提供的一个扩展点,允许开发者通过覆盖该方法实现 自定义淘汰策略(尤其是实现 LRU 缓存)。 // 返回 true,则删除最老的条目(具体“最老”含义由 accessOrder 决定) // 默认返回 false(不删除任何条目,保持标准 Map 行为) protected boolean removeEldestEntry(Map.Entry eldest) { return false; } LRU是平衡实现复杂度与效率的通用缓存策略,核心价值在于利用时间局部性,适用于数据访问模式具有“近期重复性”的场景。