缓存基础----LRU算法和FIFO算法的Java实现
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实现相关推荐
- 数据结构与算法之美笔记——基础篇(下):图、字符串匹配算法(BF 算法和 RK 算法、BM 算法和 KMP 算法 、Trie 树和 AC 自动机)
图 如何存储微博.微信等社交网络中的好友关系?图.实际上,涉及图的算法有很多,也非常复杂,比如图的搜索.最短路径.最小生成树.二分图等等.我们今天聚焦在图存储这一方面,后面会分好几节来依次讲解图相关的 ...
- 基于Huffman算法和LZ77算法的文件压缩的改进方向
基于Huffman算法和LZ77算法的文件压缩(八) 到这里已经简单实现基于Huffman算法和LZ77算法的文件压缩, GitHub源码:点我 根据基于Huffman算法和LZ77算法的文件压缩(七 ...
- 使用Apriori算法和FP-growth算法进行关联分析
目录 1. 关联分析 2. Apriori原理 3. 使用Apriori算法来发现频繁集 4. 使用FP-growth算法来高效发现频繁项集 5. 示例:从新闻网站点击流中挖掘新闻报道 扩展阅读 系列 ...
- 浅谈迪杰斯特拉(Dijkstra)算法和A*算法原理及实现
写在前面 最近我在学习一门名叫<智能自主机器人及系统>的课程,虽然跟过去所学的<机器人学>在部分内容上有所重复,但该课程的应用性更强.对于不同的机器人,如差速轮式车.四轮车.四 ...
- Widar2.0:SAGE算法和SAGE算法在在无线信道参数估计中的应用
Widar2.0:SAGE算法和SAGE算法在在无线信道参数估计中的应用 C1 本文背景 C2 SAGE算法 C2.1 EM算法 C2.2 SAGE算法 C2.3 SAGE算法和SAGE算法在在无线信 ...
- 加权无向图与最小生成树(Prim算法和Kruskal算法)
目录 0 引入 1 图的最小生成树定义及相关约定 2 最小生成树原理 2.1 性质 2.2 切分定理 3 贪心思想 4 Prim算法 4.1 算法步骤 4.2 API设计 4.3 Java代码演示 5 ...
- matlab 牛顿 科特斯的代码,SIMP算法和BESO算法的关键技术研究
摘要: 各项正交惩罚材料变密度法(SIMP算法)和双向渐进结构优化方法(BESO算法)是目前结构拓扑优化领域中应用较为广泛的两种算法.以SIMP算法和BESO算法为研究对象,通过算例分析了其各自的特性 ...
- 关联规则挖掘算法: Aprior算法和Fpgrowth算法
关联规则挖掘的目的是挖掘不同物品(item)之前的相关性,啤酒和尿布的故事就是一个典型的成功例子.关联规则挖掘思想简单高效,在广告推荐领域也有较多的应用,主要用于推荐模型落地前的流量探索以及构建规 ...
- Prime算法和Krustal算法(转自博客园华山大师兄)
Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex ( ...
最新文章
- BZOJ2131免费的馅饼 DP+树状数组
- Ghost文件封装说明
- 【C语言进阶深度学习记录】七 C语言中的循环语句
- python的print语句有哪些_Python语句print(type([1,2,3,4]))的输出结果是。
- 获取计算机主机mac地址的命令有,怎么获取计算机的MAC地址和IP地址?
- Java零基础系列003——变量
- 金蝶云·星空——采购入库单生成凭证取不到价税合计
- Windows Mobile 6 中为开发人员提供的新功能
- 无线AP 传输、认证
- Java实验-宠物商店(链表与接口的使用)
- iOS 仿微信发送语音消息按钮 - 语音播放器(三)
- 【知识兔】Excel中的F1~F12快捷键,你还不会?强大到爆~
- 超好用的在线编程IDE——CS50
- 【生信】第一二三代测序技术原理的理解
- CSS最后一行:控制寡妇和孤儿
- System.InvalidOperationException:“ConnectionString 属性尚未初始化。” 连接字符串的根本解决办法
- css一些零零散散的问题
- dir 616 虚拟服务器,DIR-616(DLink)无线路由器设置指南
- 从0开始的技术美术之路(十六)延迟渲染
- 用Python写表白程序,给另一半一个惊喜