146. LRU 缓存机制
146. LRU 缓存机制
(1)直接使用LinkedHashMap
package 链表; import java.util.LinkedHashMap; import java.util.Map; public class LRUCache extends LinkedHashMap<Integer, Integer> { private int capacity; public LRUCache(int capacity) { super(capacity, 0.75F, false); this.capacity = capacity; } public int get(int key) { return super.getOrDefault(key, -1); } public void put(int key, int value) { super.put(key, value); } @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > capacity; } }
(2)利用hashMap和双向链表实现LRU缓存
package 链表; import java.util.HashMap; public class LRUCache2 { //双向链表存元素顺序 class DeListNode { int key; int val; DeListNode next; DeListNode pre; public DeListNode() { } public DeListNode(int key, int val) { this.key = key; this.val = val; } } private int capacity; private int size = 0; // hashMap存储元素 private HashMap<Integer, DeListNode> map = new HashMap<>(); // 虚拟头尾节点 private DeListNode head; private DeListNode tail; public LRUCache2(int capacity) { this.capacity = capacity; this.head = new DeListNode(); this.tail = new DeListNode(); head.next = tail; tail.pre = head; } // 查询元素,如果不存在返回默认值,存在就把这个元素移动到链表头部 public int get(int key) { if (map.containsKey(key)) { DeListNode deListNode = map.get(key); moveToHead(deListNode); return deListNode.val; } else { return -1; } } // 插入元素,如果元素存在就替换值,并把元素移动到前边,移动到前边就是先删除再重新添加 // 如果元素不存在,就插入元素,并在双向链表头部也插入 // 容量超长了咋办 public void put(int key, int value) { if (map.containsKey(key)) { DeListNode deListNode = map.get(key); deListNode.val = value; moveToHead(deListNode); } else { DeListNode newNode = new DeListNode(key, value); addHead(newNode); map.put(key, newNode); ++size; if (size > capacity) { DeListNode removeNode = removeTail(); map.remove(removeNode.key); --size; } } } private void addHead(DeListNode node) { // 这块也会把新加入的节点和尾节点相连 node.next = head.next; node.pre = head; head.next.pre = node; head.next = node; } private void removeNode(DeListNode node) { DeListNode pre = node.pre; DeListNode next = node.next; pre.next = next; next.pre = pre; } private void moveToHead(DeListNode node) { removeNode(node); addHead(node); } private DeListNode removeTail() { DeListNode preNode = tail.pre; removeNode(preNode); return preNode; } }
。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)