【缓存算法】LRU 最近最少使用

2023-11-07

LRU是Least Recently Used,最近最少使用。
LRU缓存就是使用这种原理实现,简单的说就是缓存一定量的数据,当超过设定的阈值时就把一些过期的数据删除掉。

LRU思想

  • 固定缓存大小,需要给缓存分配一个固定的大小。
  • 每次读取缓存都会改变缓存的使用时间,将缓存的存在时间重新刷新。
  • 需要在缓存满了后,将最近最久未使用的缓存删除,再添加最新的缓存。

LRU

Java实现

  • HashMap + 双向链表
/**
 * @author huangliuyu
 * @description LRU 最近最久未使用
 * @date 2019-05-10
 */
public class LRUCache {
    private Node head;
    private Node end;
    //缓存存储上限
    private int limit;

    private HashMap<String, Node> hashMap;

    public LRUCache(int limit){
        this.limit=limit;
        hashMap=new HashMap<String, Node>();
    }


    public String get(String key){
        Node node=hashMap.get(key);
        if(null==node){
            return null;
        }
        this.refreshNode(node);
        return node.value;
    }

    public void put(String key, String value){
        Node node = hashMap.get(key);
        //如果key不存在,插入key-value
        if(null==node){
            //临界值,清理最少使用节点
            if(hashMap.size()>=limit){
                String oldKey=this.removeNode(head);
                hashMap.remove(oldKey);
            }
            node=new Node(key,value);
            this.addNode(node);
            hashMap.put(key,node);

        //如果key存在,则刷新kye-value
        }else {
            node.value=value;
            this.refreshNode(node);
        }
    }

    public void remove(String key){
        Node node=hashMap.get(key);
        this.removeNode(node);
        hashMap.remove(key);

    }

    /**
     * 刷新被访问的节点
     * @param node
     */
    private void refreshNode(Node node){
        //如果访问的尾节点,无需移动节点
        if(node ==end){
            return;
        }
        //移除节点
        this.removeNode(node);
        //重新插入节点
        this.addNode(node);
    }


    /**
     * 删除节点
     * @param node
     * @return
     */
    private String removeNode(Node node){
        if(node==end){
            //移除尾节点
            end=end.pre;
        }else if(node==head.next){
            //移除头节点
            head=head.next;
        }else {
            node.pre.next=node.next;
            node.next.pre=node.pre;
        }
        return node.key;
    }



    /**
     * 尾部插入节点
     * @param node
     */
    private void addNode(Node node){
        if(null!=end){
            end.next=node;
            node.pre=end;
            node.next=null;
        }
        end=node;
        if(null==head){
            head=node;
        }
    }



    class Node{
        public Node pre;
        public Node next;
        public String key;
        public String value;

        Node(String key, String value){
            this.key=key;
            this.value=value;
        }
    }


}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【缓存算法】LRU 最近最少使用 的相关文章

随机推荐

  • 华为 ospf 报文及邻居状态有限机

    华为 IP 路由基础 ospf 报文及邻居状态有限机 ospf协议邻居建立 一 ospf的工作机制 建立邻居 发送数据库信息 计算出最短路径 hello报文 用来建立邻居和维护邻居 邻居发现 是自动发现邻居路由器 使用的组播的地址224 0
  • docker 安装

    前提 开发环境为虚拟机Ubuntu 16 04 更换国内镜像 虚拟机是刚刚安装的 需要先更换成国内镜像源 1 首先备份原始源文件 sudo cp etc apt sources list etc apt sources list bak 2
  • RS推荐系统-LSH最近邻查找+MiniHash

    什么是最近邻查找 在推荐系统中 主要分为召回跟排序两个阶段 召回阶段 基于用户画像及场景数据从海量的视频库 百万级别 中将相关度最高的资源检索出来 作为候选集 召回阶段可以通过 粗糙 的方式召回候选item 排序阶段 基于更加精细的特征对候
  • Aspose实现word、excel、ppt转pdf

    1 工具类 AsposeUtil Component Slf4j public class AsposeUtil private static final String WORD doc docx wps wpt txt private s
  • 布隆过滤器及其实现

    简介 Bloom Filter 是由布隆 Burton Howard Bloom 在1970年提出的 loom Filter是一种空间效率很高的随机数据结构 它实际上是由一个很长的二进制向量和一系列随机映射函数组成 布隆过滤器可以用于可以快
  • kubernetes高可用集群安装(二进制安装、v1.20.2版)

    1 前言 之前文章安装 kubernetes 集群 都是使用 kubeadm 安装 然鹅很多公司也采用二进制方式搭建集群 这篇文章主要讲解 如何采用二进制包来搭建完整的高可用集群 相比使用 kubeadm 搭建 二进制搭建要繁琐很多 需要自
  • 修复Unity空白报错问题

    修复Unity空白报错问题 在升级Unity Hub之后 偶然发现Console里有几行空白的报错 看不到任何信息 由于有报错 导致修改代码无法生效 尝试重启项目 重装Unity都完全没效果 而且就算新建一个空白项目 只要添加代码就会立刻报
  • Linux操作系统原理—内核网络协议栈

    前言 本文主要记录 Linux 内核网络协议栈的运行原理 数据报文的封装与分用 封装 当应用程序用 TCP 协议传送数据时 数据首先进入内核网络协议栈中 然后逐一通过 TCP IP 协议族的每层直到被当作一串比特流送入网络 对于每一层而言
  • CASE WHEN 及 SELECT CASE WHEN的用法

    Case具有两种格式 简单Case函数和Case搜索函数 简单Case函数 CASE sex WHEN 1 THEN 男 WHEN 2 THEN 女 ELSE 其他 END Case搜索函数 CASE WHEN sex 1 THEN 男 W
  • 批量保存数据

    批量保存 批量保存 参数为对象集合 br 条件 对象属性与数据库字段完全对应 允许使用大骆驼拼写法 br 2018年4月28日下午5 30 53 throws Exception private String insert00000 Lis
  • BandZIP无广告版(v6.25)安装及禁止联网设置

    安装和设置 1 下载和安装 bandzip版本v6 25以前的都是免费且无广告的 我们从网上找到6 25版本的进行下载安装 双击 如下图进行设置 点击同意并安装 安装过程中取消自动更新 其他设置默认 安装完成后 虽然不会自动更新 但每次使用
  • C# EasyModbus xktComm Modbus 例子

    转载请注明出处 联系我 田工 15118249062 微信同号 当然先要在NuGet按照相应的dll 不是ModbusRTU报文 在RTU报文前面加了4个字节 transactionIdentifier protocolIdentifier
  • 什么是Scrum?Scrum的核心要点和精髓

    有点长 期望你能通过本文彻底了解 Scrum 我们介绍了一个非常有意思且高效的组织模式 特性团队 我们首先介绍了为什么需要特性团队 特性团队的定义 核心价值 优势 可能存在的问题以及带来的成本 接着讲述了特性团队的适用范围 开发新产品 拓展
  • alertdialog 自定义样式回调选手_把 Node.js 中的回调转换为 Promise

    每日前端夜话 第431篇 正文共 2300 字 预计阅读时间 7 分钟 介绍 在几年前 回调是 JavaScript 中实现执行异步代码的唯一方法 回调本身几乎没有什么问题 最值得注意的是 回调地狱 在 ES6 中引入了 Promise 作
  • C++中的单例模式

    单例模式也称为单件模式 单子模式 可能是使用最广泛的设计模式 其意图是保证一个类仅有一个实例 并提供一个访问它的全局访问点 该实例被所有程序模块共享 有很多地方需要这样的功能模块 如系统的日志输出 GUI应用必须是单鼠标 MODEM的联接需
  • socket选项 SO_REUSEPORT

    摘要 多核与网络IO 目录 前言 本篇用于记录学习SO REUSEPORT的笔记和心得 末尾还会提供一个bindp小工具也能为已有的程序享受这个新的特性 当前Linux网络应用程序问题 运行在Linux系统上网络应用程序 为了利用多核的优势
  • Python毕设-【基于Flask的人脸考勤系统】附源码课件_Python练手项目_JPython毕业设计

    Python毕设 基于Flask的人脸考勤系统 release 附源码课件 允许白嫖 文章目录 系统简介 一 技术框架 二 功能 三 开发工具 四 总结 五 视频演示 文末附获取方式 系统简介 基于Flask的人脸考勤系统是一种应用于公司和
  • 可视化散点图:基于R语言的碎石图

    可视化散点图 基于R语言的碎石图 在数据分析和可视化中 散点图是一种常用的工具 用于展示两个变量之间的关系 而碎石图是散点图的一种变体 能够更直观地显示数据的密度和分布情况 本文将介绍如何使用R语言创建碎石图 并通过代码演示实现过程 首先
  • 如何理解 Istio Ingress, 它与 API Gateway 有什么区别?东西流量?南北流量?

    文章目录 背景 k8s的内部服务如何被外部访问 东西流量 南北流量 流量管理的比较 Ingress API Gateway Istio 参考 背景 这三者都和流量治理密切相关 那么流量治理在过去和现在有什么区别呢 都是如何做的呢 在学习is
  • 【缓存算法】LRU 最近最少使用

    LRU是Least Recently Used 最近最少使用 LRU缓存就是使用这种原理实现 简单的说就是缓存一定量的数据 当超过设定的阈值时就把一些过期的数据删除掉 LRU思想 固定缓存大小 需要给缓存分配一个固定的大小 每次读取缓存都会