护理学院网站建设教育网站搭建

张小明 2026/1/8 19:26:47
护理学院网站建设,教育网站搭建,青岛建设网站制作,如何创建自己的软件LRU#xff08;Least Recently Used#xff0c;最近最少使用#xff09;缓存淘汰策略的核心是#xff1a;当缓存容量满时#xff0c;淘汰最久未被使用的元素。在 Java 中#xff0c;最优实现方式是结合 HashMap#xff08;快速查找#xff09;和 LinkedList/LinkedHash…LRULeast Recently Used最近最少使用缓存淘汰策略的核心是当缓存容量满时淘汰最久未被使用的元素。在 Java 中最优实现方式是结合HashMap快速查找和LinkedList/LinkedHashMap维护访问顺序其中LinkedHashMap是官方推荐的简化实现方式而手动实现双链表 哈希表能更深入理解底层原理。一、核心原理数据结构选择哈希表HashMap存储「键 - 节点」映射实现 O (1) 时间复杂度的查找 / 更新。双向链表维护节点的访问顺序头部为最近使用的节点尾部为最久未使用的节点。核心操作get(key)若键存在将节点移到链表头部标记为最近使用返回值若不存在返回 -1。put(key, value)若键存在更新值并将节点移到链表头部若键不存在创建新节点并插入链表头部同时存入哈希表若缓存容量超限删除链表尾部节点最久未使用并从哈希表中移除对应键。二、手动实现链表 HashMap手动实现能清晰体现 LRU 的核心逻辑也是面试高频考点import java.util.HashMap; import java.util.LinkedList; import java.util.Map; public class LRUCacheK, V { private final int capacity; // 缓存容量 private final MapK, V cache; // 缓存键值对 private final LinkedListK keyList; // 维护key的访问顺序尾部最近使用头部最久未使用 // 初始化校验容量合法性 public LRUCache(int capacity) { if (capacity 0) { throw new IllegalArgumentException(缓存容量必须大于0); } this.capacity capacity; this.cache new HashMap(capacity); this.keyList new LinkedList(); } // put操作存入/更新key-value保证O(1)核心逻辑仅修复逻辑未优化性能 public synchronized void put(K key, V value) { // 1. 若key已存在先移除keyList中的旧位置再删除缓存旧值 if (cache.containsKey(key)) { keyList.remove(key); // 注意此处仍为O(n)后续优化会解决 cache.remove(key); } // 2. 若缓存已满删除最久未使用的key链表头部 if (cache.size() capacity) { K oldestKey keyList.removeFirst(); cache.remove(oldestKey); } // 3. 存入新值并将key加入链表尾部标记为最近使用 cache.put(key, value); keyList.addLast(key); } // get操作获取value并更新访问顺序 public synchronized V get(K key) { // 1. 缓存中不存在key返回null if (!cache.containsKey(key)) { return null; } // 2. 存在key更新访问顺序移除旧位置加入尾部 keyList.remove(key); // 此处仍为O(n)后续优化会解决 keyList.addLast(key); return cache.get(key); } // 辅助方法打印缓存和keyList用于测试 public void printCache() { System.out.println(缓存内容 cache); System.out.println(key访问顺序 keyList); } // 测试示例 public static void main(String[] args) { LRUCacheInteger, String lru new LRUCache(2); lru.put(1, A); lru.put(2, B); lru.printCache(); // 缓存{1A, 2B}keyList[1,2] lru.get(1); // 访问1更新顺序 lru.printCache(); // 缓存{1A, 2B}keyList[2,1] lru.put(3, C); // 容量满删除最久未使用的2 lru.printCache(); // 缓存{1A, 3C}keyList[1,3] lru.put(1, AA); // 更新1的值更新顺序 lru.printCache(); // 缓存{1AA, 3C}keyList[3,1] } }三、性能优化解决 LinkedList.remove (key) 的 O (n) 问题要让get/put操作真正达到 O (1) 时间复杂度需替换 LinkedList 为「双向链表 哈希表记录节点」即我之前提到的手动实现双链表方案。以下是优化后的最终版本import java.util.HashMap; import java.util.Map; public class LRUCacheK, V { // 双向链表节点存储key、value以及前驱/后继节点 private static class NodeK, V { K key; V value; NodeK, V prev; NodeK, V next; public Node(K key, V value) { this.key key; this.value value; } } private final int capacity; // 缓存容量 private final MapK, NodeK, V nodeMap; // key - 节点O(1)查找 private final NodeK, V head; // 虚拟头节点最近使用 private final NodeK, V tail; // 虚拟尾节点最久未使用 // 初始化虚拟头尾节点相连避免空指针 public LRUCache(int capacity) { if (capacity 0) { throw new IllegalArgumentException(缓存容量必须大于0); } this.capacity capacity; this.nodeMap new HashMap(capacity); this.head new Node(null, null); this.tail new Node(null, null); head.next tail; tail.prev head; } // put操作存入/更新key-valueO(1)时间复杂度 public synchronized void put(K key, V value) { NodeK, V node nodeMap.get(key); if (node ! null) { // 1. key已存在更新value并移到头部最近使用 node.value value; moveToHead(node); return; } // 2. key不存在创建新节点 NodeK, V newNode new Node(key, value); nodeMap.put(key, newNode); addToHead(newNode); // 3. 缓存已满删除尾节点最久未使用 if (nodeMap.size() capacity) { NodeK, V tailNode removeTail(); nodeMap.remove(tailNode.key); } } // get操作获取value并更新访问顺序O(1)时间复杂度 public synchronized V get(K key) { NodeK, V node nodeMap.get(key); if (node null) { return null; } // 移到头部标记为最近使用 moveToHead(node); return node.value; } // 双向链表辅助方法均为O(1)操作 // 将节点添加到虚拟头节点之后最近使用位置 private void addToHead(NodeK, V node) { node.prev head; node.next head.next; head.next.prev node; head.next node; } // 移除指定节点 private void removeNode(NodeK, V node) { node.prev.next node.next; node.next.prev node.prev; } // 将节点移到头部先移除再添加 private void moveToHead(NodeK, V node) { removeNode(node); addToHead(node); } // 移除尾节点最久未使用 private NodeK, V removeTail() { NodeK, V tailNode tail.prev; removeNode(tailNode); return tailNode; } // 辅助方法打印缓存用于测试 public void printCache() { StringBuilder sb new StringBuilder(); NodeK, V cur head.next; while (cur ! tail) { sb.append(cur.key).append().append(cur.value).append(, ); cur cur.next; } System.out.println(缓存内容最近使用→最久未使用 sb); } // 测试示例 public static void main(String[] args) { LRUCacheInteger, String lru new LRUCache(2); lru.put(1, A); lru.put(2, B); lru.printCache(); // 1A, 2B lru.get(1); lru.printCache(); // 2B, 1A1移到最近使用 lru.put(3, C); lru.printCache(); // 1A, 3C删除最久未使用的2 lru.put(1, AA); lru.printCache(); // 3C, 1AA更新1并移到最近使用 } }
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

济南网站建设是什么意思wordpress仿互站

只要用 Kotlin 写过异步任务,就一定和协程的 Scope(作用域) 打过交道。协程作用域就像协程的“管理员”,负责调度它的启动、运行和终止。但很多人刚上手时,都会在 GlobalScope 和 Application Scope 这两个“全局级”作…

张小明 2025/12/28 8:35:12 网站建设

wordpress建站教程网软件界面设计风格

MATLAB翼型分析终极指南:XFOILinterface完整使用教程 【免费下载链接】XFOILinterface 项目地址: https://gitcode.com/gh_mirrors/xf/XFOILinterface 想要在MATLAB中轻松进行专业的翼型气动性能分析吗?XFOILinterface项目为您提供了一套完整的解…

张小明 2025/12/27 19:58:23 网站建设

网站群 推广安徽工程建设信息网新网站

Python GUI 开发:从基础到实战 1. Python 进程处理与守护进程示例 在 Python 中处理进程时,其表现得非常成熟和强大。Python 具备优雅且复杂的线程 API,但需要时刻留意全局解释器锁(GIL)。若程序是 I/O 密集型,GIL 通常不会造成问题;但如果需要使用多个处理器,那么使…

张小明 2025/12/29 6:30:00 网站建设

数据库和网站找合作项目app平台

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 开发一个多功能雨滴插件集合,包含以下5个实用功能:1) 实时CPU/内存监控仪表盘 2) 天气预报和空气质量显示 3) 音乐播放器控制面板 4) 待办事项清单 5) 系统快…

张小明 2025/12/29 6:30:28 网站建设

wordpress4.9.6漏洞seo怎么做优化工作

前段时间面试了某零售电商企业的测试经理岗位,面试官当时提了这样一个问题:我们这边测试团队开展自动化测试工作将近一年了,但目前还未看到明显的对测试过程或者质量的改善效果。如果是你,你会如何做? 自动化测试其实…

张小明 2025/12/29 1:06:14 网站建设