焦点资讯:LRU缓存与LinkedHashMap源码

今天再刷LeetCode时,遇到了第146题LRU缓存。题目如下:

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。实现 LRUCache 类:LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。示例:输入["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"][[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]输出[null, null, null, 1, null, -1, null, -1, 3, 4]解释LRUCache lRUCache = new LRUCache(2);lRUCache.put(1, 1); // 缓存是 {1=1}lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}lRUCache.get(1);    // 返回 1lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}lRUCache.get(2);    // 返回 -1 (未找到)lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}lRUCache.get(1);    // 返回 -1 (未找到)lRUCache.get(3);    // 返回 3lRUCache.get(4);    // 返回 4

如果大家有阅读过LinkedHashMap源码,就会明白,这题的解法跟LinkedHashMap源码一模一样。


(资料图片仅供参考)

大家应该经常使用HashMap,而LinkedHashMap 刚好就比 HashMap 多这一个功能就是有序。并且,LinkedHashMap的有序可以按两种顺序排列,一种是按照插入的顺序,一种是按照 读取的顺序。显然,这题便是LinkedHashMap中按照读取的顺序进行顺序排列。而其内部是靠 建立一个双向链表来维护这个顺序的,在每次插入、删除后,都会调用一个函数来进行 双向链表的维护

其内部就是靠如下三个回调方法来维护这个双向链表:

void afterNodeAccess(Node p) { }其作用就是在访问元素之后,将该元素放到双向链表的尾巴处(所以这个函数只有在按照读取的顺序的时候才会执行),之所以提这个,是建议大家去看看,如何优美的实现在双向链表中将指定元素放入链尾!void afterNodeRemoval(Node p) { }其作用就是在删除元素之后,将元素从双向链表中删除,还是非常建议大家去看看这个函数的,很优美的方式在双向链表中删除节点!void afterNodeInsertion(boolean evict) { }这个才是我们题目中会用到的,在插入新元素之后,需要回调函数判断是否需要移除一直不用的某些元素!

以下是我对于afterNodeAccess、afterNodeRemoval、afterNodeInsertion的个人理解:

afterNodeAccess:

afterNodeRemoval:

afterNodeInsertion:

/** * 插入新节点才会触发该方法,因为只有插入新节点才需要内存 * 根据 HashMap 的 putVal 方法, evict 一直是 true * removeEldestEntry 方法表示移除规则, 在 LinkedHashMap 里一直返回 false * 所以在 LinkedHashMap 里这个方法相当于什么都不做 */void afterNodeInsertion(boolean evict) { // possibly remove eldest    LinkedHashMap.Entry first;    // 根据条件判断是否移除最近最少被访问的节点    if (evict && (first = head) != null && removeEldestEntry(first)) {        K key = first.key;        removeNode(hash(key), key, null, false, true);    }}// 移除最近最少被访问条件之一,通过覆盖此方法可实现不同策略的缓存// LinkedHashMap是默认返回false的,我们可以继承LinkedHashMap然后复写该方法即可// 例如 LeetCode 第 146 题就是采用该种方法,直接 return size() > capacity;protected boolean removeEldestEntry(Map.Entry eldest) {    return false;}

通过上述代码,我们就已经知道了只要复写 removeEldestEntry() 即可,而条件就是 map 的大小不超过 给定的容量,超过了就得使用 LRU 了!然后根据题目给定的语句构造和调用:其主要是两个构造方法,一个是继承 HashMap ,一个是可以选择 accessOrder 的值(默认 false,代表按照插入顺序排序)来确定是按插入顺序还是读取顺序排序。

//调用父类HashMap的构造方法。public LinkedHashMap() {    super();    accessOrder = false;}// 这里的 accessOrder 默认是为false,如果要按读取顺序排序需要将其设为 truepublic LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {    super(initialCapacity, loadFactor);    this.accessOrder = accessOrder;}

最后该题解法如下:

class LRUCache extends LinkedHashMap {    int capacity=10;    public LRUCache(int capacity) {        super(capacity,0.75F,true);        this.capacity=capacity;    }        public int get(int key) {      return   this.getOrDefault(key,-1);    }        public void put(int key, int value) {            super.put(key,value);    }    @Override    protected boolean removeEldestEntry(Map.Entry eldest) {        return size()>capacity;    }}

完美解决!

参考链接:https://leetcode.cn/problems/lru-cache/solution/yuan-yu-linkedhashmapyuan-ma-by-jeromememory/

关键词:

为您推荐

焦点资讯:LRU缓存与LinkedHashMap源码

今天再刷LeetCode时,遇到了第146题LRU缓存。题目如下:```请你设计并实现一个满足LRU(最近最少使用)缓存约

来源:博客园2023-06-03

为好少年点赞!第六届崇左市美德少年候选人名单公示|焦点简讯

崇左市精神文明建设委员会办公室关于第六届崇左市美德少年候选人名单的公示根据《关于组织开展第六届崇左市

来源:崇左广播电视台2023-06-03

2023年临沂公积金贷款额度及利率是多少?贷款条件是什么?

临沂公积金是一项住房性质的社会福利制,符合条件的缴存职工可以享受住房公积金的各项优惠方案。那临沂公积

来源:律法网2023-06-03

环球速读:大额存单4.05%!多地银行现高利率,抢不到怎么办?不足20万呢?

大额存单4 05%!多地银行现高利率,抢不到怎么办?不足20万呢?,储户,小银行,大银行,存款利率

来源:财说得明白2023-06-03

缩小桌面空间,紧凑配列机械键盘推荐-世界看点

紧凑配列机械键盘是一种在标准键盘布局基础上进行了缩减和优化的键盘设计。它们通常采用较小的键盘尺寸,可

来源:数码休闲馆2023-06-03

2023·劳动创造幸福|雅万跨文化交融的使者_环球快资讯

“蒂娜,铜箔带和接地扁钢图纸上是螺栓连接,现场是绑扎的,需要返工,你翻译时出错了。”技术主管田明杰指

来源:中工网2023-06-03

世界快消息!赞美运动员的稿子300字左右 赞美运动员的稿子

1、5000米赞歌你象一只雄鹰,翱翔在晴空之中你象一颗金星,闪烁在宇宙之中你象一匹骏马,驰骋在战场之中没

来源:城市网2023-06-03

裸机指的是什么_裸机是什么

第一、电脑裸机是什么对于电脑裸机,不同人有不同的理解。多数人认为电脑裸机通常是指只有硬件部分,没有安

来源:互联网2023-06-03