Java 自定义实现 LRU 缓存算法
背景
LinkedHashMap继承自HashMap,内部提供了一个removeEldestEntry方法,该方法正是实现LRU策略的关键所在,且HashMap内部专门为LinkedHashMap提供了3个专用回调方法,afterNodeAccess、afterNodeInsertion、afterNodeRemoval,这3个方法的字面意思非常容易理解,就是节点访问后、节点插入后、节点删除后分别执行的行为。基于以上行为LinkedHashMap就可以实现一个LRUCache的功能了。

关于LinkedHashMap的eldest:eldest字面意思为最老的,LinkedHashMap中有个叫做accessOrder的字段,当accessOrder为true时表示LinkedHashMap内部节点按照访问次数排序,最老的节点也就是访问最少的节点。当accessOrder为false时表示LinkedHashMap内部节点按照插入顺序排序,最老的节点也就是最早插入的节点,该值默认为false。
实现
自己实现LRUCache只需覆盖removeEldestEntry这个方法即可,代码如下
private static class LRUCache<K, V> extends LinkedHashMap<K, V>
{
private static final long serialVersionUID = -9111855653176630846L;
private static int MAX_ELEMENTS;
public LRUCache(int initCap, int maxSize) throws IllegalArgumentException
{
super(initCap, 0.75f, true);
if (maxSize < 0)
throw new IllegalArgumentException();
MAX_ELEMENTS = maxSize;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest)
{
return size() > MAX_ELEMENTS;
}
}
以上代码需要一个MAX_ELEMENTS变量限制最大存储节点个数,插入节点时判断 如果当前节点个数已经超过了这个值则会根据LRU策略将访问最少的那个节点删除,这里需要注意,默认LinkedHashMap保证的是插入顺序,也就是节点按照插入先后来排序的,所以就算删除也是删除最先插入的节点,但是我们在构造函数中传入了一个true,这个参数决定了LinkedHashMap内部的节点按照什么方式排序,参数为true时说明内部节点按照最近访问的时间排序,为false时说明按照插入顺序排序。至此已完成了一个简易的LRUCache实现。
注意
由于LinkedHahsMap本身实现不是线程安全的,也就是说这个LRUCache也不是线程安全的,如果想要能多线程访问的话,可以这样使用它:LRUCache cache = Collections.synchronizedMap(new LRUCache(10, 10))。这样cache就可以在多线程下执行get/put等操作了,但是,用这种方式得到的cache在多线程遍历时还是不安全的。所以不能在多线程下遍历cache,官方文档也建议在遍历synchronizedmap时使用map本身做同步。
Java 自定义实现 LRU 缓存算法的更多相关文章
- 面试挂在了 LRU 缓存算法设计上
好吧,有人可能觉得我标题党了,但我想告诉你们的是,前阵子面试确实挂在了 RLU 缓存算法的设计上了.当时做题的时候,自己想的太多了,感觉设计一个 LRU(Least recently used) 缓存 ...
- 如何用LinkedHashMap实现LRU缓存算法
阿里巴巴笔试考到了LRU,一激动忘了怎么回事了..准备不充分啊.. 缓存这个东西就是为了提高运行速度的,由于缓存是在寸土寸金的内存里面,不是在硬盘里面,所以容量是很有限的.LRU这个算法就是把最近一次 ...
- HashMap+双向链表手写LRU缓存算法/页面置换算法
import java.util.Hashtable; class DLinkedList { String key; //键 int value; //值 DLinkedList pre; //双向 ...
- LRU缓存算法与pylru
这篇写的略为纠结,算法原理.库都是现成的,我就调用了几个函数而已,这有啥好写的?不过想了想,还是可以介绍一下LRU算法的原理及简单的用法. LRU(Least Recently Used,最近最少 ...
- LinkedHashMap实现LRU缓存算法
LinkedHashMap的get()方法除了返回元素之外还可以把被访问的元素放到链表的底端,这样一来每次顶端的元素就是remove的元素. 构造函数如下: public LinkedHashMap ...
- LRU缓存算法 - C++版
LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法. 实现思路: hashtable + 双向链表 时间复杂度: 插入,查找,删除:O(1) 空间使用 ...
- LRU缓存算法
http://blog.csdn.net/beiyeqingteng/article/details/7010411 http://blog.csdn.net/wzy_1988/article/det ...
- LRU缓存实现(Java)
LRU Cache的LinkedHashMap实现 LRU Cache的链表+HashMap实现 LinkedHashMap的FIFO实现 调用示例 LRU是Least Recently Used 的 ...
- [转]LRU缓存实现(Java)
LRU Cache的LinkedHashMap实现 LRU Cache的链表+HashMap实现 LinkedHashMap的FIFO实现 调用示例 LRU是Least Recently Used 的 ...
随机推荐
- MongoDB命令行操作
本文专门介绍MongoDB的命令行操作.其实,这些操作在MongoDB官网提供的Quick Reference上都有,但是英文的,为了方便,这里将其稍微整理下,方便查阅. 这里用来做测试的是远端(10 ...
- 第23讲 UI_布局 之相对布局
第23讲 UI_布局 之相对布局 .RelativeLayout(相对布局): RelativeLayout(相对布局)是指组件的位置总是相对兄弟组件.父容器来决定的(相对位置),如某个组件的左边右边 ...
- 有关JAVA基础学习中的集合讨论
很高兴能在这里认识大家,我也是刚刚接触后端开发的学习者,相信很多朋友在学习中都会遇到很多头疼的问题,希望我们都能够把问题分享出来,把自己的学习思路整理出来,我们一起探讨一起成长. 今天我 ...
- 关于时间的操作(JavaScript版)——依据不同区时显示对应的时间
如今项目基本上告一段落了,难得有一定的闲暇,今天利用数小时完毕了一个功能模块--依据不同区时显示对应的时间,这方面网上基本没有现成的样例,如今将代码粘贴例如以下: <!DOCTYPE HTML ...
- HDU--1584--蜘蛛牌--深搜版本号
蜘蛛牌 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- Hadoop集群运行JNI程序
要在Hadoop集群运行上运行JNI程序,首先要在单机上调试程序直到可以正确运行JNI程序,之后移植到Hadoop集群就是水到渠成的事情. Hadoop运行程序的方式是通过jar包,所以我们需要将所有 ...
- java基础之数组
数组的定义 数组的应用 1, 2, 3, 4,
- HTML5 prefetch即预加载
原文地址 声明:此文带着自己的理解,不完全按原文翻译 prefetch 即预加载,在用户需要前我们就将所需的资源加载完毕. 有了浏览器缓存,为何还需要预加载? 用户可能是第一次访问网站,此时还无缓存 ...
- C#编写Windows服务程序图文教程(转载)
Windows Service这一块并不复杂,但是注意事项太多了,网上资料也很凌乱,偶尔自己写也会丢三落四的.所以本文也就产生了,本文不会写复杂的东西,完全以基础应用的需求来写,所以不会对Window ...
- (转)通过在 Page 指令或 配置节中设置 validateRequest=false 可以禁用请求验证
通过在 Page 指令或 配置节中设置 validateRequest=false 可以禁用请求验证 说明: 请求验证过程检测到有潜在危险的客户端输入值,对请求的处理已经中止.该值可能指示危及应用 ...