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);
 */
相关推荐
跟着珅聪学java39 分钟前
spring boot +Elment UI 上传文件教程
java·spring boot·后端·ui·elementui·vue
我命由我123451 小时前
Spring Boot 自定义日志打印(日志级别、logback-spring.xml 文件、自定义日志打印解读)
java·开发语言·jvm·spring boot·spring·java-ee·logback
lilye661 小时前
程序化广告行业(55/89):DMP与DSP对接及数据统计原理剖析
java·服务器·前端
想跑步的小弱鸡4 小时前
Leetcode hot 100(day 3)
算法·leetcode·职场和发展
战族狼魂4 小时前
CSGO 皮肤交易平台后端 (Spring Boot) 代码结构与示例
java·spring boot·后端
xyliiiiiL5 小时前
ZGC初步了解
java·jvm·算法
杉之6 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
爱的叹息6 小时前
RedisTemplate 的 6 个可配置序列化器属性对比
算法·哈希算法
hycccccch6 小时前
Canal+RabbitMQ实现MySQL数据增量同步
java·数据库·后端·rabbitmq
独好紫罗兰6 小时前
洛谷题单2-P5713 【深基3.例5】洛谷团队系统-python-流程图重构
开发语言·python·算法