LRU经典算法的原理与实现
LRU least recently used.顾名思义,是根据数据的活跃度进行更新的缓存算法。
LRU Cache的LinkedHashMap实现:
LinkedHashMap自身已经实现了顺序存储,默认情况下是按照元素的添加顺序存储,也可以启用按照访问顺序存储,即最近读取的数据放在最前面,最早读取的数据放在最后面,然后它还有一个判断是否删除最老数据的方法,默认是返回false,即不删除数据,我们使用LinkedHashMap实现LRU缓存的方法就是对LinkedHashMap实现简单的扩展,扩展方式有两种,一种是inheritance,一种是delegation,具体使用什么方式看个人喜好
//LinkedHashMap的一个构造函数,当参数accessOrder为true时,即会按照访问顺序排序,最近访问的放在最前,最早访问的放在后面
public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
} //LinkedHashMap自带的判断是否删除最老的元素方法,默认返回false,即不删除老数据
//我们要做的就是重写这个方法,当满足一定条件时删除老数据
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return false;
}
采用inheritance方式实现比较简单,而且实现了Map接口,在多线程环境使用时可以使用 Collections.synchronizedMap()方法实现线程安全操作
package cn.lzrabbit.structure.lru; import java.util.LinkedHashMap;
import java.util.Map; /**
* Created by liuzhao on 14-5-15.
*/
public class LRUCache2<K, V> extends LinkedHashMap<K, V> {
private final int MAX_CACHE_SIZE; public LRUCache2(int cacheSize) {
super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true);
MAX_CACHE_SIZE = cacheSize;
} @Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_CACHE_SIZE;
} @Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (Map.Entry<K, V> entry : entrySet()) {
sb.append(String.format("%s:%s ", entry.getKey(), entry.getValue()));
}
return sb.toString();
}
}
这样算是比较标准的实现吧,实际使用中这样写还是有些繁琐,更实用的方法时像下面这样写,省去了单独见一个类的麻烦
final int cacheSize = 100;
Map<String, String> map = new LinkedHashMap<String, String>((int) Math.ceil(cacheSize / 0.75f) + 1, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
return size() > cacheSize;
}
};
LRU缓存LinkedHashMap(delegation)实现
delegation方式实现更加优雅一些,但是由于没有实现Map接口,所以线程同步就需要自己搞定了
package cn.lzrabbit.structure.lru; import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set; /**
* Created by liuzhao on 14-5-13.
*/
public class LRUCache3<K, V> { private final int MAX_CACHE_SIZE;
private final float DEFAULT_LOAD_FACTOR = 0.75f;
LinkedHashMap<K, V> map; public LRUCache3(int cacheSize) {
MAX_CACHE_SIZE = cacheSize;
//根据cacheSize和加载因子计算hashmap的capactiy,+1确保当达到cacheSize上限时不会触发hashmap的扩容,
int capacity = (int) Math.ceil(MAX_CACHE_SIZE / DEFAULT_LOAD_FACTOR) + 1;
map = new LinkedHashMap(capacity, DEFAULT_LOAD_FACTOR, true) {
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_CACHE_SIZE;
}
};
} public synchronized void put(K key, V value) {
map.put(key, value);
} public synchronized V get(K key) {
return map.get(key);
} public synchronized void remove(K key) {
map.remove(key);
} public synchronized Set<Map.Entry<K, V>> getAll() {
return map.entrySet();
} public synchronized int size() {
return map.size();
} public synchronized void clear() {
map.clear();
} @Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (Map.Entry entry : map.entrySet()) {
sb.append(String.format("%s:%s ", entry.getKey(), entry.getValue()));
}
return sb.toString();
}
}
注:此实现为非线程安全,若在多线程环境下使用需要在相关方法上添加synchronized以实现线程安全操作
LRU经典算法的原理与实现的更多相关文章
- Java中的经典算法之冒泡排序(Bubble Sort)
Java中的经典算法之冒泡排序(Bubble Sort) 神话丿小王子的博客主页 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一 ...
- Java中的经典算法之选择排序(SelectionSort)
Java中的经典算法之选择排序(SelectionSort) 神话丿小王子的博客主页 a) 原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕.也就是:每一趟 ...
- JS的十大经典算法排序
引子 有句话怎么说来着: 雷锋推倒雷峰塔,Java implements JavaScript. 当年,想凭借抱Java大腿火一把而不惜把自己名字给改了的JavaScript(原名LiveScript ...
- mahout中kmeans算法和Canopy算法实现原理
本文讲一下mahout中kmeans算法和Canopy算法实现原理. 一. Kmeans是一个很经典的聚类算法,我想大家都非常熟悉.虽然算法较为简单,在实际应用中却可以有不错的效果:其算法原理也决定了 ...
- 机器学习经典算法详解及Python实现--基于SMO的SVM分类器
原文:http://blog.csdn.net/suipingsp/article/details/41645779 支持向量机基本上是最好的有监督学习算法,因其英文名为support vector ...
- 经典算法题每日演练——第八题 AC自动机
原文:经典算法题每日演练--第八题 AC自动机 上一篇我们说了单模式匹配算法KMP,现在我们有需求了,我要检查一篇文章中是否有某些敏感词,这其实就是多模式匹配的问题. 当然你也可以用KMP算法求出,那 ...
- 非对称加密技术- RSA算法数学原理分析
非对称加密技术,在现在网络中,有非常广泛应用.加密技术更是数字货币的基础. 所谓非对称,就是指该算法需要一对密钥,使用其中一个(公钥)加密,则需要用另一个(私钥)才能解密. 但是对于其原理大部分同学应 ...
- PageRank算法--从原理到实现
本文将介绍PageRank算法的相关内容,具体如下: 1.算法来源 2.算法原理 3.算法证明 4.PR值计算方法 4.1 幂迭代法 4.2 特征值法 4.3 代数法 5.算法实现 5.1 基于迭代法 ...
- K-means算法的原理、优缺点及改进(转)
文章内容转载自:http://blog.csdn.net/sinat_35512245/article/details/55051306 ...
随机推荐
- dedecms使用
使用到了dedecms内容管理系统,遇到两个问题: 1.点击登录后,没有登录进去也没有任何提示,一片空白 解决办法:我是把网站从云主机拷贝下来的,但是忘了云主机上的数据库密码和自己本地的数据库密码不一 ...
- 使用淘宝 NPM 镜像
http://www.runoob.com/nodejs/nodejs-npm.html ************************************** 大家都知道国内直接使用 npm ...
- 循环节计算---用到find函数
#include <iostream> #include <algorithm> #include <vector> using namespace std; in ...
- java -jar命令
1.用eclipse的export导出jar包后,打开jar中的MANIFEST.MS文件,修改如下: 2.然后在命令行中输入命令:java -jar aa.jar即可.
- 辛星和你彻底搞清CSS中的相对定位和绝对定位
前面我在解读CSS中也说过了关于相对定位和绝对定位的问题.无奈还是有些童鞋表示迷茫,于是另开一篇博客,来具体解读相对定位和绝对定位.希望可以以我的点点星光,让后来者少走弯路. 所谓相对定位,就是设置为 ...
- 基于ZK的分布式锁实现
import java.util.concurrent.TimeUnit; import org.apache.curator.framework.CuratorFramework; import o ...
- ZABBIX监控原理
zabbix实现原理及架构详解 想要用好zabbix进行监控,那么我们首要需要了解下zabbix这个软件的实现原理及它的架构.建议多阅读官方文档. 一.总体上zabbix的整体架构如下图所示: 重 ...
- 微信小程序4 - 几个ES6基础写法
1. 默认参数 function demo(param){ param=param || {};} 新的写法,很直观 function demo(param={}){} 2. 简化方法,如你所见,de ...
- 一个共通的viewModel搞定所有的分页查询一览及数据导出(easyui + knockoutjs + mvc4.0)
前言 大家看标题就明白了我想写什么了,在做企业信息化系统中可能大家写的最多的一种页面就是查询页面了.其实每个查询页面,除了条件不太一样,数据不太一样,其它的其实都差不多.所以我就想提取一些共通的东西出 ...
- 第二百四十三节,Bootstrap模态框插件
Bootstrap模态框插件 学习要点: 1.基本使用 2.用法说明 本节课我们主要学习一下 Bootstrap 中的模态框插件,这是一款交互式网站非常常见的 弹窗功能插件. 一.基本使用 使用模态框 ...