Java里面实现LRU缓存算法的通常有两种选择,一种是自己设计数据结构:链表+HashMap(链表用来表示位置,哈希表用来存储和查找),另一种是使用Java中的LinkedHashMap。我们这边文章是使用Java的LinkedHashMap来实现缓存的LRU算法和FIFO算法。

一、LinkedHashMap实现缓存LRU算法

LinkedHashMap有两种数据的存储方式,一种是按照数据的添加顺序存储,另一种是按照数据的访问顺序存储,默认情况下是按照数据的添加顺序存储的。即最近读取的数据放在链表头部,最早读取的数据放在链表尾部。并且LinkedHashMap还有一个判断是否删除老数据的方法,默认返回false,即不删除数据。我们通过LinkedHashMap实现LRU缓存就是继承LinkedHashMap类并重写父类的removeEldestEntry方法。代码如下:

/*** LinkedHashMap实现LRU算法* @author Administrator**/
public class CacheLRU<K, V> extends LinkedHashMap<K, V>
{private static final long serialVersionUID = 1L;/** 元素最大值,当数据个数超过最大值时,就要删除一些很久没有被访问到的数据*/private final int MAX_CACHE_SIZE;/*** CacheLRU构造函数,调用父类LinkedHashMap的构造函数* @param cacheSize 缓存数据的最大值*/public CacheLRU(int cacheSize) {/** 调用父类构造函数,当参数accessOrder为true时,即会按照访问顺序排序,最近访问的放在最前,最早访问的放在后面* (int) Math.ceil(cacheSize / 0.75) + 1  计算LinkedHashMap的初始化容量*/super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true);//元素最大值MAX_CACHE_SIZE = cacheSize;}/*** 重写LinkedHashMap的removeEldestEntry方法,removeEldestEntry方法是LinkedHashMap自带的判断是否删除最老元素的方法,默认返回false,即不删除老数据*/@Overrideprotected boolean removeEldestEntry(Map.Entry<K, V> eldest) {//当linkedhashmap中数据量大于指定的最大值时,返回true,就自动删除老数据return size() > MAX_CACHE_SIZE;}}

但是实际使用中这样写还是有些繁琐,更实用的方法时像下面这样写,省去了单独见一个类的麻烦

private final int cacheSize = 100;
Map<String, Integer> map = new LinkedHashMap<String, Integer>((int) Math.ceil(cacheSize/0.75f) + 1, 0.75f, true) {@Overrideprotected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {return size() > cacheSize;}
};

二、LinkedHashMap实现缓存FIFO算法

FIFO算法的核心思想是先进先出,即按照添加顺序最先添加的数据最先被删除。默认情况下LinkedHashMap就是按照数据的添加顺序存储的,所以实现FIFO算法时,我们只需重写下removeEldestEntry方法即可轻松实现一个FIFO缓存算法。代码如下:

public class CacheFIFO<K, V> extends LinkedHashMap<K, V>
{private static final long serialVersionUID = 1L;/** 元素最大值,当数据个数超过最大值时,就要删除一些很久没有被访问到数据*/private final int MAX_CACHE_SIZE;/*** CacheFIFO构造函数,这里不用调用父类的LinkedHashMap构造函数* FIFO原则就是先进先出的,默认情况下LinkedHashMap就是按照添加顺序保存,所以不需要更改排序方式,只需要重写removeEldestEntry方法即可* @param cacheSize 缓存数据的最大值*/public CacheFIFO(int cacheSize) {this.MAX_CACHE_SIZE = cacheSize;}/*** 重写LinkedHashMap的removeEldestEntry方法,removeEldestEntry方法是LinkedHashMap自带的判断是否删除最老元素的方法,默认返回false,即不删除老数据*/@Overrideprotected boolean removeEldestEntry(Map.Entry<K, V> eldest) {//当linkedhashmap中数据量大于指定的最大值时,返回true,就自动删除老数据return size() > MAX_CACHE_SIZE;}}

简化版的实现代码如下:

private final int cacheSize = 5;
LinkedHashMap<String, Integer> lru = new LinkedHashMap<String, Integer>() {@Overrideprotected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {return size() > cacheSize;}
};

三、调用示例

测试代码如下:

public class CacheLRUTest
{public static void main(String[] args){System.out.println("===========================LRU LinkedHashMap实现开始===========================");CacheLRU<String, Integer> lru = new CacheLRU<String, Integer>(5);//存入数据,最大值为5for(int i=0; i<5; i++) {lru.put("test"+i, i);}System.out.println("目前所有缓存为:" +lru.toString());//最近访问的几个数据lru.get("test0");lru.get("test3");lru.get("test3");lru.get("test4");//新添加两个数据lru.put("test5", 5);lru.put("test6", 6);System.out.println("删除老数据后所有缓存为:" +lru.toString());System.out.println("===========================LRU LinkedHashMap实现结束===========================");System.out.println();System.out.println();System.out.println("===========================FIFO LinkedHashMap实现开始===========================");CacheFIFO<String, Integer> fifo = new CacheFIFO<String, Integer>(5);//存入数据,最大值为5for(int i=0; i<5; i++) {fifo.put("test"+i, i);}System.out.println("目前所有缓存为:" +fifo.toString());//最近访问的几个数据fifo.get("test1");fifo.get("test1");fifo.get("test2");fifo.get("test3");//新添加两个数据fifo.put("test5", 5);fifo.put("test6", 6);System.out.println("删除老数据后所有缓存为:" +fifo.toString());System.out.println("===========================FIFO LinkedHashMap实现结束===========================");}}

运行结果如下:

===========================LRU LinkedHashMap实现开始===========================
目前所有缓存为:{test0=0, test1=1, test2=2, test3=3, test4=4}
删除老数据后所有缓存为:{test0=0, test3=3, test4=4, test5=5, test6=6}
===========================LRU LinkedHashMap实现结束======================================================FIFO LinkedHashMap实现开始===========================
目前所有缓存为:{test0=0, test1=1, test2=2, test3=3, test4=4}
删除老数据后所有缓存为:{test2=2, test3=3, test4=4, test5=5, test6=6}
===========================FIFO LinkedHashMap实现结束===========================

缓存基础----LRU算法和FIFO算法的Java实现相关推荐

  1. 数据结构与算法之美笔记——基础篇(下):图、字符串匹配算法(BF 算法和 RK 算法、BM 算法和 KMP 算法 、Trie 树和 AC 自动机)

    图 如何存储微博.微信等社交网络中的好友关系?图.实际上,涉及图的算法有很多,也非常复杂,比如图的搜索.最短路径.最小生成树.二分图等等.我们今天聚焦在图存储这一方面,后面会分好几节来依次讲解图相关的 ...

  2. 基于Huffman算法和LZ77算法的文件压缩的改进方向

    基于Huffman算法和LZ77算法的文件压缩(八) 到这里已经简单实现基于Huffman算法和LZ77算法的文件压缩, GitHub源码:点我 根据基于Huffman算法和LZ77算法的文件压缩(七 ...

  3. 使用Apriori算法和FP-growth算法进行关联分析

    目录 1. 关联分析 2. Apriori原理 3. 使用Apriori算法来发现频繁集 4. 使用FP-growth算法来高效发现频繁项集 5. 示例:从新闻网站点击流中挖掘新闻报道 扩展阅读 系列 ...

  4. 浅谈迪杰斯特拉(Dijkstra)算法和A*算法原理及实现

    写在前面 最近我在学习一门名叫<智能自主机器人及系统>的课程,虽然跟过去所学的<机器人学>在部分内容上有所重复,但该课程的应用性更强.对于不同的机器人,如差速轮式车.四轮车.四 ...

  5. Widar2.0:SAGE算法和SAGE算法在在无线信道参数估计中的应用

    Widar2.0:SAGE算法和SAGE算法在在无线信道参数估计中的应用 C1 本文背景 C2 SAGE算法 C2.1 EM算法 C2.2 SAGE算法 C2.3 SAGE算法和SAGE算法在在无线信 ...

  6. 加权无向图与最小生成树(Prim算法和Kruskal算法)

    目录 0 引入 1 图的最小生成树定义及相关约定 2 最小生成树原理 2.1 性质 2.2 切分定理 3 贪心思想 4 Prim算法 4.1 算法步骤 4.2 API设计 4.3 Java代码演示 5 ...

  7. matlab 牛顿 科特斯的代码,SIMP算法和BESO算法的关键技术研究

    摘要: 各项正交惩罚材料变密度法(SIMP算法)和双向渐进结构优化方法(BESO算法)是目前结构拓扑优化领域中应用较为广泛的两种算法.以SIMP算法和BESO算法为研究对象,通过算例分析了其各自的特性 ...

  8. 关联规则挖掘算法: Aprior算法和Fpgrowth算法

      关联规则挖掘的目的是挖掘不同物品(item)之前的相关性,啤酒和尿布的故事就是一个典型的成功例子.关联规则挖掘思想简单高效,在广告推荐领域也有较多的应用,主要用于推荐模型落地前的流量探索以及构建规 ...

  9. Prime算法和Krustal算法(转自博客园华山大师兄)

     Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex ( ...

最新文章

  1. BZOJ2131免费的馅饼 DP+树状数组
  2. Ghost文件封装说明
  3. 【C语言进阶深度学习记录】七 C语言中的循环语句
  4. python的print语句有哪些_Python语句print(type([1,2,3,4]))的输出结果是。
  5. 获取计算机主机mac地址的命令有,怎么获取计算机的MAC地址和IP地址?
  6. Java零基础系列003——变量
  7. 金蝶云·星空——采购入库单生成凭证取不到价税合计
  8. Windows Mobile 6 中为开发人员提供的新功能
  9. 无线AP 传输、认证
  10. Java实验-宠物商店(链表与接口的使用)
  11. iOS 仿微信发送语音消息按钮 - 语音播放器(三)
  12. 【知识兔】Excel中的F1~F12快捷键,你还不会?强大到爆~
  13. 超好用的在线编程IDE——CS50
  14. 【生信】第一二三代测序技术原理的理解
  15. CSS最后一行:控制寡妇和孤儿
  16. System.InvalidOperationException:“ConnectionString 属性尚未初始化。” 连接字符串的根本解决办法
  17. css一些零零散散的问题
  18. dir 616 虚拟服务器,DIR-616(DLink)无线路由器设置指南
  19. 从0开始的技术美术之路(十六)延迟渲染
  20. 用Python写表白程序,给另一半一个惊喜

热门文章

  1. 我的世界服务器生存模式维护,生存模式 - Minecraft Wiki,最详细的官方我的世界百科...
  2. JNA实战系列:第一个简单的JNA开发程序
  3. IIC通信协议详解[转载]
  4. 小明今年12岁,他母亲比他大24岁
  5. 绘画新手入门如何临摹画画
  6. windows10升级助手_Windows 10最简单的重装方式,会用鼠标就行
  7. PTA浙大版《C语言程序设计(第3版)》习题4-8 高空坠球
  8. 蓝桥杯VIP题目免费提交,内含超详解,步步截图!!!
  9. 网络与信息安全学习(一)
  10. 新晋总监生存指南四——项目执行指南