java实现LRU 缓存

如果碰到这种题⽬先不要慌张,现在脑海⾥回忆⼀遍 LRU 的基本概念:LRU(Least Recently Used,最近最少使⽤)是⼀种缓存算法,其核⼼思想是将最近最少使⽤的缓存项移除,以便为更常 ⽤的缓存项腾出空间。

适⽤场景:

  • 频繁访问:LRU 算法适⽤于那些有频繁访问的数据,⽐如缓存、⻚⾯置换等场景。
  • 有局部性:当访问模式具有局部性,即近期访问的数据更可能在未来被再次访问时,LRU 算法 能够有较好的表现。
  • 数据访问分布均匀:如果数据的访问分布较为均匀,没有出现热点数据或周期性访问模式, LRU 算法的命中率较⾼。
  • 缓存容ᰁ适中:LRU 算法适⽤于缓存容ᰁ适中的场景,过⼤的缓存可能导致淘汰开销增⼤,⽽过⼩的缓存则可能导致频繁缓存失效。

在 Java 中,可以使⽤ LinkedHashMap 来实现 LRU 缓存。使⽤LinkedHashMap实现 LRU 缓存可 以极⼤地简化代码,因为LinkedHashMap已经内置了按照访问顺序排序的功能。所以使⽤LinkedHashMap 确实可以避免⼿动实现双向链表和节点的逻辑。

为了使⽤ LinkedHashMap 来实现 LRU 缓存,在创建 LinkedHashMap 对象时设置它的访问顺序为 true,这样元素将按照访问顺序进⾏排序。然后,我们可以重写它的 removeEldestEntry ⽅法来控制 是否移除最⽼的数据。

java 复制代码
import java.util.LinkedHashMap;
import java.util.Map;
public class LRUCache<K,V> extends LinkedHashMap<K, V> {
    private int capacity;

    public LRUCache(int capacity){
        super(capacity,0.75f, true);
        this.capacity = capacity;
    }

    public void setValue(K key, V value){
        super.put(key, value);
    }

    public V getValue(K key){
        return super.getOrDefault(key,null);
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > capacity;
    }

    public static void main(String[] args) {
        LRUCache<Integer, String> lruCache = new LRUCache<>(4);
        lruCache.setValue(1, "a");
        lruCache.setValue(2, "b");
        lruCache.setValue(3, "c");
        lruCache.setValue(4, "d");

        System.out.println(lruCache.getValue(1));

        lruCache.put(5, "e");
        System.out.println(lruCache.getValue(2));
    }
}

加深巩固:

leecode: 146. LRU 缓存 - 力扣(LeetCode)

题解:

java 复制代码
class LRUCache extends LinkedHashMap<Integer,Integer>{
    private int capacity;
    public LRUCache(int capacity) {
        super(capacity,0.75f,true); // 开启accessOrder属性,访问元素后将访问的元素放到链表末端
        this.capacity = capacity;
    }
    
    public int get(int key) {
        return super.getOrDefault(key, -1); // 如果存在,将会放到链表末端表示它是最近使用的。
    }
    
    public void put(int key, int value) {
        super.put(key,value);
    }

    //  判断size超过容量时返回true,告知LinkedHashMap移除最老的缓存项(即链表的第一个元素)
    @Override
    public boolean removeEldestEntry(Map.Entry<Integer,Integer> eldest) {
        return size() > capacity;   
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */
相关推荐
卡尔特斯1 小时前
Android Kotlin 项目代理配置【详细步骤(可选)】
android·java·kotlin
白鲸开源1 小时前
Ubuntu 22 下 DolphinScheduler 3.x 伪集群部署实录
java·ubuntu·开源
ytadpole1 小时前
Java 25 新特性 更简洁、更高效、更现代
java·后端
纪莫2 小时前
A公司一面:类加载的过程是怎么样的? 双亲委派的优点和缺点? 产生fullGC的情况有哪些? spring的动态代理有哪些?区别是什么? 如何排查CPU使用率过高?
java·java面试⑧股
JavaGuide2 小时前
JDK 25(长期支持版) 发布,新特性解读!
java·后端
用户3721574261352 小时前
Java 轻松批量替换 Word 文档文字内容
java
白鲸开源2 小时前
教你数分钟内创建并运行一个 DolphinScheduler Workflow!
java
CoovallyAIHub3 小时前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
Java中文社群3 小时前
有点意思!Java8后最有用新特性排行榜!
java·后端·面试
代码匠心3 小时前
从零开始学Flink:数据源
java·大数据·后端·flink