设计一个LRU Cache

本文介绍了一种基于HashMap和双向链表实现LRUCache的方法,支持插入、替换及查找操作,时间复杂度均为O(1)。通过扩展LinkedHashMap并调整其移除最旧条目的策略,实现了LRU缓存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原来遇到的一个面试题,今天意外想起,记录一下。


问题:设计实现一个LRU Cache,需要支持三种操作:插入(insert)、替换(replace)、查找(lookup)

思路:用HashMap做为基础容器,容器内Value组成双向链表,由双向链表支持LRU的替换策略。

链表需要维持数据项从最近访问到最旧访问的顺序。

  • 插入:当Cache未满时,新的数据项只需插到双链表头部即可。时间复杂度为O(1)O(1).

  • 替换:当Cache已满时,将新的数据项插到双链表头部,并删除双链表的尾结点即可。时间复杂度为O(1)O(1).

  • 查找:每次数据项被查询到时,都将此数据项移动到链表头部。

实现:

Java实现非常简单,LinkedHashMap自身已经实现了顺序存储,默认情况下是按照元素的添加顺序存储,也可以启用按照访问顺序存储,即最近读取的数据放在最前面,最早读取的数据放在最后面,然后它还有一个判断是否删除最老数据的方法,默认是返回false,即不删除数据,我们使用LinkedHashMap实现LRU缓存的方法就是对LinkedHashMap实现简单的扩展。



public static class LRULinkedHashMap<K, V> extends LinkedHashMap<K, V> {  
  
        /** serialVersionUID */  
        private static final long serialVersionUID = -5933045562735378538L;  
  
        /** 最大数据存储容量 */  
        private static final int  LRU_MAX_CAPACITY     = 1024;  
  
        /** 存储数据容量  */  
        private int               capacity;  
  
        /** 
         * 默认构造方法 
         */  
        public LRULinkedHashMap() {  
            super();  
        }  
  
        /** 
         * 带参数构造方法 
         * @param initialCapacity   容量 
         * @param loadFactor        装载因子 
         * @param isLRU             是否使用lru算法,true:使用(按方案顺序排序);false:不使用(按存储顺序排序) 
         */  
        public LRULinkedHashMap(int initialCapacity, float loadFactor, boolean isLRU) {  
            super(initialCapacity, loadFactor, true);  
            capacity = LRU_MAX_CAPACITY;  
        }  
  
        /** 
         * 带参数构造方法 
         * @param initialCapacity   容量 
         * @param loadFactor        装载因子 
         * @param isLRU             是否使用lru算法,true:使用(按方案顺序排序);false:不使用(按存储顺序排序) 
         * @param lruCapacity       lru存储数据容量        
         */  
        public LRULinkedHashMap(int initialCapacity, float loadFactor, boolean isLRU, int lruCapacity) {  
            super(initialCapacity, loadFactor, true);  
            this.capacity = lruCapacity;  
        }  
  
        /**  
         * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) 
         */  
        @Override  
        protected boolean removeEldestEntry(Entry<K, V> eldest) {  
            System.out.println(eldest.getKey() + "=" + eldest.getValue());  
              
            if(size() > capacity) {  
                return true;  
            }  
            return false;  
        }  
    } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值