使用LinkedHashMap实现LRU算法

使用LinkedHashMap实现LRU算法

LRU算法,最近最少使用原则,如果要实现该算法,可以借助LinkedHashMap数据结构,LinkedHashMap继承HashMap,底层使用哈希表和双向链表来保存所有元素,使用LinkedHashMap可以确保元素按照顺序进行存储。

默认情况下,LinkedHashMap是按照元素的添加顺序存储,也可以启用按照访问顺序存储,即最近读取的数据放在最前面,最早读取的数据放在最后面,然后它还有一个判断是否删除最老数据的方法,默认是返回false,即不删除数据。

下面就基于这两种存储方式,简单展示一下如何实现LRU算法:

 

一、基于按添加顺序存储的方式实现LRU:

public class LRUTest
{
    int capacity;
    LinkedHashMap<Integer, Integer> cache;

    LRUTest(int capacity)
    {
        cache = new LinkedHashMap<>();
        this.capacity = capacity;
    }

    //访问元素
    public int get(int key)
    {
        if(!cache.containsKey(key))
        {
            return -1;
        }

        //存在,先从链表头部删除删除,在插入到链表尾部
        int val = cache.get(key);
        cache.remove(key);
        cache.put(key, val);

        return val;
    }

    //添加元素
    public void put(int key, int val)
    {
        if(cache.containsKey(key))
        {
            cache.remove(key);
        }

        //如果链表已经满了,则删除头部节点
        if(cache.size() == capacity)
        {
            Set<Integer> keySet = cache.keySet();
            Iterator<Integer> iterator = keySet.iterator();
            cache.remove(iterator.next());
        }

        cache.put(key, val);
    }
}

 

二、基于按访问顺序存储的方式实现LRU:

该方式的核心就是继承LinkedHashMap,并设置LinkedHashMap的accessOrder参数为true,然后重写LinkedHashMap的removeEldestEntry()方法。

public class LRUTest extends LinkedHashMap<String, String>
{
    private int capacity;

    /**
     * 当LinkedHashMap的accessOrder参数为true时,即会按照访问顺序排序,最近访问的放在最前,最早访问的放在后面
     */
    public LRUTest(int capacity) {
        super(16, 0.75f, true);
        this.capacity = capacity;
    }

    /**
     * LinkedHashMap自带的判断是否删除最老的元素方法,默认返回false,即不删除老数据
     */
    @Override
    protected boolean removeEldestEntry(Map.Entry<String, String> eldest)
    {
        return size() > capacity;
    }
}

测试方法:

    public static void main(String[] args)
    {
        Map<String, String> linkedHashMap = new LRUTest(6);

        linkedHashMap.put("1", "1");
        linkedHashMap.put("2", "2");
        linkedHashMap.put("3", "3");
        linkedHashMap.put("4", "4");
        linkedHashMap.put("5", "5");
        linkedHashMap.put("6", "6");
        linkedHashMap.put("7", "7");
        linkedHashMap.put("8", "8");
        linkedHashMap.put("9", "9");

        System.out.println("size="+linkedHashMap.size());
        System.out.println(linkedHashMap.get("8"));

        linkedHashMap.forEach((k,v) ->{
            System.out.print(k + ":"+ v +"  ");
        });

        System.out.println();
        System.out.println("size="+linkedHashMap.size());
    }

输出结果:

size=6
8
4:4  5:5  6:6  7:7  9:9  8:8  
size=6

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/100026.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • MySQL数据类型选择「建议收藏」

    MySQL数据类型选择「建议收藏」前言在MySQL中,选择正确的数据类型,对于性能至关重要。一般应从以下两个方面考量:确定合适的大类型:数值、字符串、时间、二进制;确定具体的类型:有无符号、取值范围、变长定长等。在MySQL数据类型设置方面,尽量采用更小的数据类型,因为它们占用的存储空间更小,通常有更好的性能,花费更少的硬件资源。并且,尽量把字段定义为NOTNULL,避免使用NULL。1.字符串类型类型大小用途CHAR0-255字节定长字符串,char(n)当插入的字符串实际长度不足n时,插

    2022年9月20日
    0
  • Python代码库_Python编程

    Python代码库_Python编程实例:绘制蟒蛇#PythonDraw.pyimportturtleturtle.setup(650,350,200,200)turtle.penup()turtle.fd(-25

    2022年8月5日
    0
  • java 登录 qq_Java实现QQ登录

    java 登录 qq_Java实现QQ登录packagecom.ck.blog.controller;importcom.alibaba.fastjson.JSONObject;importcom.ck.blog.exception.StateErrorException;importcom.ck.blog.utils.QQHttpClient;importorg.springframework.beans.factory.an…

    2022年7月8日
    24
  • 教你PSD文件如何预览(支持32以及64位win7系统)

    教你PSD文件如何预览(支持32以及64位win7系统)相信随着软矿发出关于AdobeCS6的系列文章,很多矿友们已经按捺不住都早早的安装上了吧!但是笔者安装之后发现之前安装的PhotoshopCS5所具有的PSD文件预览功能消失了,相当郁闷的说~所以苦寻很多方法之后终于找到了消失的PSD文件预览功能。NO.1下载右侧链接的压缩包文件:点我下载下载完成后解压缩至任意目录,压缩包内容如下图所示然后将对应系统的MysticThum…

    2022年6月11日
    50
  • GitHub 标星 2.9w+,我发现了一个宝藏项目,作为编程新手有福了!「建议收藏」

    GitHub 标星 2.9w+,我发现了一个宝藏项目,作为编程新手有福了!「建议收藏」大家好,我是Rocky0429,一个最近老在GitHub上闲逛的蒟蒻…特别惭愧的是,虽然我很早就知道GitHub,但是学会逛GitHub的时间特别晚。当时一方面是因为菜,看着这种全是英文的东西难受,不知道该怎么去玩,另一方面是一直在搞ACM,没有做一些工程类的项目,所以想当然的以为和GitHub也没什么关系(当然这种想法是错误的)。后来自己花了一个星期看完了Pyt…

    2022年6月17日
    28
  • python license函数_Python 自动获取License文件

    python license函数_Python 自动获取License文件1importos2importsys3importjson4importtime567#returndependenciesstring8#forexample:9#'”axios”:”^0.19.2″,”myjs-common”:”^1.0.6″,”oneport”:”^1.0.2″’10defreadPackageJson(filename):11de…

    2022年7月26日
    12

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号