LRU的java实现

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: LRU的java实现

什么是LRU


LRU(Least Recently Used)直译来看,就是最近最少使用,因为LRU是一个淘汰算法,所以指的是,每次都淘汰离当前时间最远的被使用到的那一个。也就是最久没有被使用到的那个。


为什么需要LRU


LRU其实大部分操作系统为最大化页面命中率而广泛采用的一种页面置换算法,是为了提高页面的命中率而使用的算法,就应用开发来说,Redis的内存淘汰策略使用的就是LRU算法,当Redis内存使用打到上限,如果采用的 allkeys-lru 删除策略,此时我们再增加key,redis就会根据LRU来挑选一个key进行删除。


LRU的使用场景


  • 操作系统的一些内存管理,页面置换算法


  • redis/memcache/mysql


  • 业务使用


LRU的实现方案


对于添加新的k-v,和删除已存在的key,我们都想达到O(1)的时间复杂度,所以我们使用双向链表+hash的实现方案。


hashmap负责定位数据位置,双向链表负责转移和增减数据。


涉及到删除的话,那我们使用的链表应该是个定长链表,当满了的时候,进行LRU的删除。


代码如下:


package com.vipkid.modelserving.web;
import java.util.HashMap;
import java.util.LinkedList;
public class LRUCache {
    private int capacity;
    //hashmap
    private HashMap<Integer,Integer> map;
    //双向链表
    private LinkedList<Integer> list;
    //初始化容量
    public LRUCache(int capacity) {
        this.capacity=capacity;
        map=new HashMap<>();
        list=new LinkedList<Integer>();
    }
    //取值,存在则将最新访问的挪到最后
    public int get(int key) {
        //key存在
        if (map.containsKey(key)){
            list.remove(key);
            //移到最后
            list.addLast(key);
            return map.get(key);
        }
        return -1;
    }
    //存入值,存在则将最新访问的挪到最后
    //不存在则存入最后,若容量满,从最开始开始删除
    public void put(int key, int value) {
        //key 已存在
        if (map.containsKey(key)){
            //删除旧的
            list.remove(key);
            //放到最后
            list.addLast(key);
            return;
        }
        //key不存在,满了
        if (list.size()==capacity){
            //从最开始开始删除
            int remove=list.removeFirst();
            map.remove(remove);
            map.put(key,value);
            list.addLast(key);
        }else {
            //key不存在,没满
            map.put(key,value);
            list.addLast(key);
        }
    }
}
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
3月前
|
存储 缓存 Java
|
6月前
|
存储 缓存 Java
java如何实现一个LRU(最近最少使用)缓存?
实现了一个LRU缓存,使用双向链表保持访问顺序,哈希表用于定位元素。Java代码中,`LRUCache`类包含容量、哈希表及链表头尾节点。`get`方法查哈希表,找到则移动至链表头并返回值,否则返回-1。`put`方法更新或插入节点,超出容量则移除最不常用节点。
57 6
|
6月前
|
缓存 算法 Java
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
|
6月前
|
Java Go C++
Java每日一练(20230427) 螺旋矩阵、LRU缓存机制、解数独
Java每日一练(20230427) 螺旋矩阵、LRU缓存机制、解数独
47 0
Java每日一练(20230427) 螺旋矩阵、LRU缓存机制、解数独
|
6月前
|
存储 缓存 Java
java如何实现一个LRU(最近最少使用)缓存? 要求:设计一个LRU缓存,支持get和put操作。当缓存满时,需要淘汰最近最少使用的元素。要求使用双向链表+哈希表的数据结构来实现,并保证get和put操作的时间复杂度为O(1)。
java如何实现一个LRU(最近最少使用)缓存? 要求:设计一个LRU缓存,支持get和put操作。当缓存满时,需要淘汰最近最少使用的元素。要求使用双向链表+哈希表的数据结构来实现,并保证get和put操作的时间复杂度为O(1)。
63 1
|
6月前
|
存储 缓存 Java
146. LRU 缓存 --力扣 --JAVA
​ 请你设计并实现一个满足  LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。 void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。 函数 get
49 0
|
算法 Java
Java - 快速手撕 LRU 算法
Java - 快速手撕 LRU 算法
186 0
|
存储 缓存 算法
昨天面试被问到的 缓存淘汰算法FIFO、LRU、LFU及Java实现
在高并发、高性能的质量要求不断提高时,我们首先会想到的就是利用缓存予以应对。 第一次请求时把计算好的结果存放在缓存中,下次遇到同样的请求时,把之前保存在缓存中的数据直接拿来使用。 但是,缓存的空间一般都是有限,不可能把所有的结果全部保存下来。那么,当缓存空间全部被占满再有新的数据需要被保存,就要决定删除原来的哪些数据。如何做这样决定需要使用缓存淘汰算法。 常用的缓存淘汰算法有:FIFO、LRU、LFU,下面我们就逐一介绍一下。
312 0
|
存储 缓存 算法
Java集合详解5:深入理解LinkedHashMap和LRU缓存
《Java集合详解系列》是我在完成夯实Java基础篇的系列博客后准备开始写的新系列。 这些文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star、fork哈 文章首发于我的个人博客: www.how2playlife.com 今天我们来深入探索一下LinkedHashMap的底层原理,并且使用linkedhashmap来实现LRU缓存。