手写LRU缓存的两种实现方式
创作时间:
作者:
@小白创作中心
手写LRU缓存的两种实现方式
引用
CSDN
1.
https://blog.csdn.net/agonie201218/article/details/136935173
LRU(Least Recently Used)缓存是一种常见的数据结构,用于实现缓存淘汰策略。本文将介绍两种实现LRU缓存的方法:使用Java自带的LinkedHashMap类和手写链表+HashMap的实现方式。
使用 LinkedHashMap 实现LRU 缓存
我们可以封装一个简易版的 LRU(LeastRecentlyUsed,最近最少使用) 缓存,确保当存放的元素超过容器容量时,将最近最少访问的元素移除。
具体实现思路如下:
- 继承
LinkedHashMap; - 构造方法中指定
accessOrder为 true ,这样在访问元素时就会把该元素移动到链表尾部,链表首元素就是最近最少被访问的元素; - 重写
removeEldestEntry方法,该方法会返回一个 boolean 值,告知LinkedHashMap是否需要移除链表首元素(缓存容量有限)。
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int capacity;
public LRUCache(int capacity) {
super(capacity, 0.75f, true);
this.capacity = capacity;
}
/**
* 判断size超过容量时返回true,告知LinkedHashMap移除最老的缓存项(即链表的第一个元素)
*/
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > capacity;
}
}
将 accessOrder 设置为 true 并重写 removeEldestEntry 方法当链表大小超过容量时返回 true,使得每次访问一个元素时,该元素会被移动到链表的末尾。一旦插入操作让 removeEldestEntry 返回 true 时,视为缓存已满, LinkedHashMap 就会将链表首元素移除,由此我们就能实现一个 LRU 缓存。
LinkedHashMap 定义了排序模式 accessOrder(boolean 类型,默认为 false),访问顺序则为 true,插入顺序则为 false。
手写LRU(链表+hashmap)
import java.util.HashMap;
class LRUCache {
class Node {
int key;
int value;
Node prev;
Node next;
}
private void addNode(Node node) {
node.prev = head;
node.next = head.next;
head.next.prev = node;
head.next = node;
}
private void removeNode(Node node) {
Node prev = node.prev;
Node next = node.next;
prev.next = next;
next.prev = prev;
}
private void moveToHead(Node node) {
removeNode(node);
addNode(node);
}
private Node popTail() {
Node res = tail.prev;
removeNode(res);
return res;
}
private HashMap<Integer, Node> cache = new HashMap<>();
private int size;
private int capacity;
private Node head, tail;
public LRUCache(int capacity) {
this.size = 0;
this.capacity = capacity;
head = new Node();
tail = new Node();
head.next = tail;
tail.prev = head;
}
public int get(int key) {
Node node = cache.get(key);
if (node == null) {
return -1;
}
moveToHead(node);
return node.value;
}
public void put(int key, int value) {
Node node = cache.get(key);
if (node == null) {
Node newNode = new Node();
newNode.key = key;
newNode.value = value;
cache.put(key, newNode);
addNode(newNode);
size++;
if (size > capacity) {
Node tail = popTail();
cache.remove(tail.key);
size--;
}
} else {
node.value = value;
moveToHead(node);
}
}
}
热门推荐
如何安全拆除房屋?这种拆除如何减少潜在风险?
汪曾祺的香港印象
骨盆修复手法,真的有效吗?
中医针灸减肥:传统智慧的科学实践与安全指南
腹腔镜与开腹胰十二指肠切除术治疗壶腹周围肿瘤的比较研究
北美石膏板市场规模与趋势分析
室內養殖花卉如何解決病害問題
7种安全移除眼内异物的方法
遗产侵占如何举证
笔记本4060和4070差距大吗 性能解析与选择指南
电气工程师需要具备的核心技能
透过数字看成效 上海自贸试验区80条试点措施已基本落地
如何在Windows操作系统环境中更新BIOS
三相异步变速电机,工作原理和应用场景分析
甜味剂大揭秘:从天然到人工,解析甜味的秘密
梦回青白瓷韵:饶玉陶瓷三十余年坚守再现宋文化风采
智能手环与车载蓝牙冲突吗?冲突时应如何处理?
急性结膜炎传染别人吗
变道发生交通事故就一定是全责吗?超速50%-70%会吊销驾驶证吗?
手机如何设置照片储存到SD卡
西妥昔单抗及类似物竞争格局
艾灸治疗近视眼:原理、方法与注意事项
近视真的不可逆吗?中医视角为你揭开近视防控的奥秘
医疗器械质量管理体系怎么建立?
发热、咳嗽、嗜睡……和感冒相似的脑膜炎,要留意3个特殊症状
红枣有去湿气的作用吗
大脸型选眼镜全攻略:不同脸型的完美镜框搭配技巧
新疆一男子朝人吐口水,对方索赔2万元,法院判了
伸缩皮带机货物间距综合控制策略
如何增重最快?健康增重3步驟與增胖的錯誤迷思