集合系列(二十六) -利用LinkedHashMap实现一个LRU缓存

news2024/9/20 14:31:38

一、什么是 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、微服务等技术栈。

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ 网络套接字编程 tcp udp

文章目录 网络通信的本质tcp 和 udp 协议网络字节序网络主机数据转化接口 udp 通信服务端逻辑客户端逻辑 TCP 通信服务端程序编写步骤客户端程序编写步骤 两种通信程序代码udp服务端程序编写udp 客户端程序编写tcp 服务端程序编写tcp 客户端程序编写 网络通信的本质 网络之间的…

香港电讯高可用网络助力企业变革金融计算

客户背景 客户是一家金融行业知名的量化私募对冲基金公司&#xff0c;专注于股票、期权、期货、债券等主要投资市场&#xff0c;在量化私募管理深耕多年&#xff0c;目前资管规模已达数百亿级&#xff0c;在国内多个城市均设有办公地点。 客户需求 由于客户业务倚重量化技术…

内网渗透-隧道搭建ssp隧道代理工具frp内网穿透技术

内网渗透-隧道搭建&ssp隧道代理工具&frp内网穿透 内网穿透&#xff1a;解决网络控制上线&网络通讯问题 隧道技术&#xff1a;解决不出网协议上线的问题&#xff08;利用出网协议进行封装出网&#xff09; 代理技术&#xff1a;解决网络通讯不通的问题&#xff0…

C++ —— unordered_set、unordered_map的介绍及使用

目录 unordered系列关联式容器 unordered_set的介绍 unordered_set的使用 unordered_set的定义方式 unordered_set接口的使用 unordered_multiset unordered_map的介绍 unordered_map的使用 unordered_map的定义方式 unordered_map接口的使用 unordered_multimap …

【两数之和】

两数之和 一、题目二、暴力解法三、哈希表四、map字典1.基本方法.set()添加键值对.get()通过键获取值.has()判断map是否有这个键 2.map和set的联系和区别共同点共同点MapSet 一、题目 二、暴力解法 三、哈希表 解题思路&#xff1a;将nums的元素依次以键值对的方式存储在map字典…

怎么看OV泛域名证书市场占有率提升

近年来&#xff0c;随着网络安全的逐渐普及&#xff0c;使用SSL证书的站点也逐渐增多。https证书也成为了当下最受欢迎的数字证书之一&#xff0c;主要是用于保护网站和应用程序的安全&#xff0c;并提升用户对网站的信任度&#xff0c;且只有企业或组织才可申请OV级别的SSL证书…

VMware虚拟机三种网络模式设置 - Bridged(桥接模式)

一、前言 由于linux目前很热门&#xff0c;越来越多的人在学习linux&#xff0c;但是买一台服务放家里来学习&#xff0c;实在是很浪费。那么如何解决这个问题&#xff1f;虚拟机软件是很好的选择&#xff0c;常用的虚拟机软件有vmware workstations和virtual box等。 在使用虚…

uniapp app一键登录

一键登录不需要单独写页面&#xff0c;uniapp 有原生的页面 第一步&#xff0c;登录Dcloud后台》我的应用》点击应用名称 填写完点击 uniCloud模块新建一个服务空间》选择免费 , 创建完点击一键登录&#xff0c;添加应用&#xff0c;这个需要审核&#xff0c;“大概一天左右”…

yolov10官方demo

python环境3.9 GitHub - THU-MIG/yolov10: YOLOv10: Real-Time End-to-End Object Detection 将模型移动到项目目录下 项目执行导入依赖 conda create -n yolov10 python3.9 conda activate yolov10 pip install -r requirements.txt pip install -e .

鸿萌的成功案例:数据“失而复得”的奇迹,奥睿科磁盘阵列恢复记

2024 年 6 月 3 日&#xff0c;鸿萌收到了来自大连某客户的一台奥睿科 ORICO 3548RUS3 四盘位 DAS 磁盘阵列。 故障背景 故障设备如下图所示&#xff0c;它曾经承载了客户满满的信赖与期待。 ORICO 3548RUS3 四盘位 DAS 磁盘阵列 有时&#xff0c;命运的转折让人猝不及防&am…

全新防关联技术出炉:亚马逊测评环境优化,下单成功率大提升

在竞争激烈的测评行业中&#xff0c;构建一个稳定且高效的环境系统成为了制胜的关键。然而&#xff0c;市场上现有的环境方案如虚拟机、模拟机、GCS、云手机、VPS等不仅成本高昂&#xff0c;而且面临着在风控严格的平台上如亚马逊难以逃脱检测的挑战&#xff0c;进而影响了测评…

决策树算法:揭示数据背后的决策逻辑

目录 一 决策树算法原理 特征选择 信息增益 信息增益比 基尼指数 树的构建 树的剪枝 预剪枝 后剪枝 二 决策树算法实现 一 使用决策树进行分类 数据预处理 构建决策树模型 二 使用决策树进行回归 数据预处理 构建决策树回归模型 三 决策树算法的优缺点 优点 …

发力采销,京东的“用户关系学”

作者 | 曾响铃 文 | 响铃说 40多岁打扮精致的城市女性&#xff0c;在西藏那曲的偏远农村&#xff0c;坐着藏民的摩托车&#xff0c;行驶在悬崖边的烂泥路上&#xff0c;只因为受顾客的“委托”&#xff0c;要寻找最原生态的藏区某款产品。 30多岁的憨厚中年男性&#xff0c;…

ROM修改进阶教程------小米机型不解锁bl 刷写国际版固件 rom修改解析

众所周知,小米机型要刷写国际版固件需要解锁bl先。否则开机会进不去系统。报错。究其原因是因为有区域限制。目前。在国外安卓论坛上已经有作者分享了一些国内版无需解锁bl刷写国际版固件的资源。 本人下载了一些固件通过与官方固件的对比了解了其中的一些区别,可能有网友询…

基于Baichuan2的新冠流感中医自我诊断治疗(大模型微调+Gradio)

一、项目说明 项目使用paddleNLP提供的大模型套件对Baichuan2-7b/13b进行微调&#xff0c;使用《中医治疗新冠流感支原体感染等有效病历集》进行Lora训练&#xff0c;使大模型具备使用中医方案诊断和治疗新冠、流感等上呼吸道感染的能力。 二、PaddleNLP PaddleNLP提供的飞桨…

2024最新宝塔面板8.1.0企业版开心版

官方更新记录 【增加】增加【网站】-【HTML项目】 【优化】优化Docker模块使用体验 【优化】优化文件压缩和解压的速度 【修复】修复在上一版本中出现的所有已知问题 开心版更新记录 1.在 PHP切换页面&#xff0c;出现报错弹窗属于正常情况&#xff0c;是因爲没安装 企业…

Chrome插件开发入门:手把手教你创建第一个扩展

问题背景 最近&#xff0c;客户发布了一个新的任务 —— 开发一个Chrome插件。之前没有这方面的开发经验&#xff0c;准备想学习一下这块的内容&#xff0c;我发现网上的大多数视频都是几年前的&#xff0c;开发版本都是基于MV2&#xff0c;当前谷歌已经开始使用MV3&#xff0…

【嵌入式编程】-C语言结构体成员对齐、填充和数据打包

C语言结构体成员对齐、填充和数据打包 文章目录 C语言结构体成员对齐、填充和数据打包1、内存中的数据对齐2、C语言中的结构填充3、如何减少结构填充4、C语言中结构填充的常见问题解答 在 C 语言中&#xff0c;结构用作数据包。它们不提供任何数据封装或数据隐藏功能。在本文中…

HarmonyOS【ArkUI组件--TextInput】

1.文本输入框基本用法 2. 使用文本输入框组件&#xff08;如何实现输入数字改变图片大小&#xff09; 在此博客的基础上继续编写&#xff1a;HarmonyOS【ArkUI组件--Text】-CSDN博客 ①代码如下&#xff1a; import font from ohos.font Entry Component struct Index {State …

【吊打面试官系列-Mysql面试题】Myql 中的事务回滚机制概述 ?

大家好&#xff0c;我是锋哥。今天分享关于 【Myql 中的事务回滚机制概述 ?】面试题&#xff0c;希望对大家有帮助&#xff1b; Myql 中的事务回滚机制概述 ? 事务是用户定义的一个数据库操作序列&#xff0c;这些操作要么全做要么全不做&#xff0c;是一个不可分割的工作单位…