利用LinkedHashMap实现一个LRU缓存

一、什么是 LRU

LRU是 Least Recently Used 的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰

简单的说就是,对于一组数据,例如:int[] a = {1,2,3,4,5,6},如果1,2这几个数字经常被使用,那么会排在3,4,5,6的后面,数组变成如下:int[] a = {3,4,5,6,1,2},如果一个数字,经常不被使用,就会排在最前面!

LRU 算法,一般用于热点数据的查询,比如新闻信息,越是能被用户看得多的新闻,越有可能被别的用户所看到,对于那种基本没人访问的新闻,基本都类似存入大海!

在 Java 中,就有这么一个集合类实现了这个功能,它就是LinkedHashMap

二、LinkedHashMap 实现介绍

我们都知道,在java集合中,LinkedHashMap 继承自 HashMap,底层是一个双向链表的数据结构,与 HashMap 不同的是,LinkedHashMap 初始化阶段有个参数accessOrder ,默认是false

public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>{
    /**双向链表的头节点*/
    transient LinkedHashMap.Entry<K,V> head;
    /**双向链表的尾节点*/
    transient LinkedHashMap.Entry<K,V> tail;
    /**
      * 1、如果accessOrder为true的话,则会把访问过的元素放在链表后面,放置顺序是访问的顺序
      * 2、如果accessOrder为false的话,则按插入顺序来遍历
      */
      final boolean accessOrder;
}

如果传入的是true,则会把最近访问过的元素放在链表后面,放置顺序是访问的顺序,测试如下:

public static void main(String[] args) {
        //accessOrder默认为false
        Map<String, String> accessOrderFalse = new LinkedHashMap<>();
        accessOrderFalse.put("1","1");
        accessOrderFalse.put("2","2");
        accessOrderFalse.put("3","3");
        accessOrderFalse.put("4","4");
        System.out.println("acessOrderFalse:"+accessOrderFalse.toString());

        //accessOrder设置为true
        Map<String, String> accessOrderTrue = new LinkedHashMap<>(16, 0.75f, true);
        accessOrderTrue.put("1","1");
        accessOrderTrue.put("2","2");
        accessOrderTrue.put("3","3");
        accessOrderTrue.put("4","4");
        accessOrderTrue.get("2");//获取键2
        accessOrderTrue.get("3");//获取键3
        System.out.println("accessOrderTrue:"+accessOrderTrue.toString());
}

输出结果如下:

acessOrderFalse:{1=1, 2=2, 3=3, 4=4}
accessOrderTrue:{1=1, 4=4, 2=2, 3=3}

可以得知,当我们将accessOrder设置为true的时候,经常被访问的元素会放入前面!

我们利用这个特性,使用 LinkedHashMap 来实现一个 LRU 缓存,操作如下:

  • 创建一个 LinkedHashMap 对象,将accessOrder设置为true
  • 设定 LinkedHashMap 的容量为n,超过这个值就删除多余的元素;
  • 重写 LinkedHashMap 中removeEldestEntry()方法;

其中removeEldestEntry()表示,如果返回的是true,就会移除最近不被使用的元素,如果返回false,不做任何操作,这个方法每次在add()的时候就会调用。

创建一个 LRU 缓存类,内容如下:

public class LRULinkedHashMap<K, V> extends LinkedHashMap<K, V> {

    //创建一个容量为3的LinkedHashMap
    private static final int MAX_SIZE = 3;

    /**
     * 重写LinkedHashMap中removeEldestEntry方法
     * @param eldest
     * @return
     */
    protected boolean removeEldestEntry(Map.Entry eldest) {
        //如果容器中的元素个数大于MAX_SIZE,在每次添加元素的时候,移除容器中最近不被使用的元素
        return size() > MAX_SIZE;
    }

    public LRULinkedHashMap() {
        //设置LinkedHashMap初始化容量,负载因子为0.75f,accessOrder设置为true
        super(MAX_SIZE, 0.75f, true);
    }
}

测试使用:

public static void main(String[] args) {
    LRULinkedHashMap<String,String> cache = new LRULinkedHashMap<String,String>();
    cache.put("1","a");
    cache.put("2","b");
    cache.put("3","c");
    System.out.println("初始cache内容:" + cache.toString());
    cache.get("2");
    System.out.println("查询key为2的元素之后,cache内容:" + cache.toString());
    cache.put("4","d");
    System.out.println("添加新的元素之后,cache内容:" + cache.toString());
}

输出结果如下:

初始cache内容:{1=a, 2=b, 3=c}
查询key为2的元素之后,cache内容:{1=a, 3=c, 2=b}
添加新的元素之后,cache内容:{3=c, 2=b, 4=d}

三、小结

在实际的业务开发过程中,LRU 算法应用比较广泛,比如热点排行榜,设置容量为3的时候,会将不常用的新闻移除,保留最新的热点信息。

写到最后

不会有人刷到这里还想白嫖吧?点赞对我真的非常重要!在线求赞。加个关注我会非常感激!

本文已整理到技术笔记中,此外,笔记内容还涵盖 Spring、Spring Boot/Cloud、Dubbo、JVM、集合、多线程、JPA、MyBatis、MySQL、微服务等技术栈。

需要的小伙伴可以点击 技术笔记 获取!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/726573.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux - 输入输出

一、输出格式 echo //末尾自带换行 -n //取消自带换行 -e //支持转移符 常见转义符 \n换行 \t制表符 printf // 格式化输出字符串 %-10s // %s代表字符串 -10 左对齐容纳10个字符 二、输入输出重定向 file descriptors &#x…

leetcode (top100)接雨水

题目&#xff1a; 题解&#xff1a; 可以把每个宽度看作一个桶&#xff0c;每个桶能接的水等于这个桶左右两个方向最高桶的最小高度再减去这个桶本身的高度。把每个桶能接的水相加即可。 难点在于如何快速找到当前桶的左右两个方向的最高桶的高度&#xff0c;可以先遍历一遍…

LangChain入门到精通,看这这篇吊打面试官

导语 在人工智能领域的不断发展中&#xff0c;语言模型扮演着重要的角色。特别是大型语言模型&#xff08;LLM&#xff09;&#xff0c;如ChatGPT&#xff0c;已经成为科技领域的热门话题&#xff0c;并受到广泛认可。在这个背景下&#xff0c;LangChain作为一个以LLM模型为核…

什么是元数据管理?企业进行元数据管理可以满足什么目的?

元数据管理作为数据治理的重要组成部分&#xff0c;其作用日益凸显。元数据&#xff0c;即“关于数据的数据”&#xff0c;提供了对数据的描述、上下文和意义的详细信息&#xff0c;对于确保数据的准确性、一致性和可访问性至关重要。 有效的元数据管理能够帮助企业更好地理解…

数位统计DP——AcWing 338. 计数问题

数位统计DP 定义 数位DP&#xff08;Digital DP&#xff09;是一种用于解决与数字的数位相关问题的动态规划算法。它将数字的每一位看作一个状态&#xff0c;通过转移状态来计算满足特定条件的数字个数或其他相关统计信息。 运用情况 统计满足特定条件的数字个数&#xff0…

好用的抖音短视频矩阵系统推荐:筷子剪辑,超级编导。抖去推

目前短视频矩阵行业如火如荼&#xff0c;为大家推荐几款比较好用的短视频矩阵系统。 第一款叫做筷子剪辑&#xff0c;由筷子科技开发&#xff0c;网页版应用工具&#xff0c;无需下载安装 主打视频剪辑&#xff0c;支持一键成片&#xff0c;视频发布等&#xff0c;&#xff0…

SAP赋能食品行业,确保安全与品质的双重飞跃

品安全与品质是消费者最关心的问题&#xff0c;也是食品企业的生命线。随着科技的发展和消费者需求的日益多样化&#xff0c;食品行业正面临着前所未有的挑战和机遇。SAP作为全球领先的企业资源规划&#xff08;ERP&#xff09;系统&#xff0c;为食品行业提供了全面的解决方案…

基于STC12C5A60S2系列1T 8051单片机接收串口调试助手发送的固定长度字符串控制单片机的功能

基于STC12C5A60S2系列1T 8051单片机接收串口调试助手发送的固定长度字符串控制单片机的功能 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机串口通信介绍STC12C5A60S2系列1T 8051单片机串口通信的结构基于STC12C5A60S2系列1T 8051单片机串口通信的特殊功能…

21.0docker企业级镜像仓库harbor(vmware 中国团队)

docker企业级镜像仓库harbor(vmware 中国团队) 网站下载harbor软件包 https://github.com/goharbor/harbor 查看软件安装harbor版本需求限制 本地环境需求已满足 点击下载harbor安装包 点击releases根据版本信息下载 下面的在线安装就是docker pull。离线就是下载之后…

Flask新手入门(一)

前言 Flask是一个用Python编写的轻量级Web应用框架。它最初由Armin Ronacher作为Werkzeug的一个子项目在2010年开发出来。Werkzeug是一个综合工具包&#xff0c;提供了各种用于Web应用开发的工具和函数。自发布以来&#xff0c;Flask因其简洁和灵活性而迅速受到开发者的欢迎。…

【Java】已解决java.sql.SQLRecoverableException异常

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决java.sql.SQLRecoverableException异常 在Java的数据库编程中&#xff0c;java.sql.SQLRecoverableException是一个重要的异常&#xff0c;它通常表示一个可以恢复的SQL异常。…

重磅!鹅厂大牛带你30分钟玩转AI智能结对编程!

在大模型时代&#xff0c;人工智能技术的突破性进展正重塑着软件开发的面貌。AI的融入不仅优化了代码编写过程&#xff0c;更开启了智能编程的新纪元&#xff0c;为开发者带来了前所未有的工作效率和创新可能。AI结对编程不仅能够极大提升研发效率&#xff0c;还能通过智能分析…

每月策略会议

周一顾问策略会议&#xff0c;对于企业辅导而言&#xff0c;领导力是可以培训的&#xff0c;而决策力不是靠培训就能达成&#xff0c;是需要反复训练和反思。从最为关心的一个状况出发&#xff0c;去行动才会有结果&#xff0c;有了结果反思我们的假设是否有盲区是否有误才有可…

登录安全分析报告:链家地产

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

一机两用是什么

什么是一机两用&#xff0c;一机两用的解决什么问题&#xff1f; 其实&#xff0c;一机两用就是零信任防泄漏沙箱解决方案。 在国内&#xff0c;很多保密性质较高的企事业单位面临着如何在保证业务流畅和工作效率的同时&#xff0c;确保信息高安全性的挑战。为了应对这个问题&…

VMware Ubuntu 虚拟机网卡消失及解决办法

VMware Ubuntu 虚拟机网卡消失 描述原因查找解决方法 描述 在正常使用过程中重启后发现 VMware Ubuntu 虚拟机中的网卡消失了&#xff0c;使用 ifconfig 查看只能看到本地回环&#xff1a; 原因查找 使用如下命令查看是否和我这边遇到的问题一致的原因。 sudo lshw -c netwo…

微信公众号绑定开发者后端,报错“系统发生错误,请稍后重试”的坑

一、问题描述 在公众号后端填写完基本配置&#xff0c;点击保存&#xff0c;发现提示“系统发生错误&#xff0c;请稍后重试”。联系公众号客服回复&#xff0c;涉及开发内容不给支持-_-|| 二、经多次百度&#xff0c;结合实际尝试&#xff0c;总结解决方案如下&#xff1a;…

SYD881X读取GATT VALUE的长度

SYD881X读取GATT VALUE的长度 现在具体遇到这样一个需要&#xff0c;机器生产后要更新profile&#xff0c;这个只能够通过升级4K来做&#xff0c;但是需要知道profile是否改变了&#xff0c;这个就要知道profile是否改变来决定是否要升级&#xff0c;这里的做法是增加一个函数&…

Jenkins+gitee流水线部署springboot项目

目录 前言 一、软件版本/仓库 二、准备工作 2.1 安装jdk 11 2.2 安装maven3.9.7 2.3 安装docker 2.4 docker部署jenkins容器 三、jenkins入门使用 3.1 新手入门 3.2 jenkins设置环境变量JDK、MAVEN、全局变量 3.2.1 jenkins页面 3.2.2 jenkins容器内部终端 3.2.3 全…

如何选择理想CDN服务商来提升网站性能

在数字时代&#xff0c;网络速度已成为衡量网站成功的关键指标之一。快速加载的网站不仅提升用户体验&#xff0c;还对网站的搜索引擎排名产生显著影响。用户期望网站能够迅速响应其请求&#xff0c;而任何延迟都可能导致用户不满和流失。研究表明&#xff0c;网站加载时间的每…