LRU 实现缓存
LRU:Least Recently used 最近最少使用
1.使用LinkedHashMap实现 inheritance实现方式 继承map类 可以使用Collections.synchronizedMap方式实现线程安全的操作
public class LruCache<K,V> extends LinkedHashMap<K,V> {
private final int MAX_CACHE_SIZE;
public LruCache(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();
}
}
2、LinkedHashMap 使用delegation方式实现
没有map接口
public class LruByDelegation<K,V> {
private final int MAX_CACHE_SIZE;
private final float DEFAULT_LOAD_FACTOR = 0.75f;
LinkedHashMap<K,V> map;
public LruByDelegation(int cacheSize) {
this.MAX_CACHE_SIZE = cacheSize;
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();
}
}
2 Cache链表+HashMap实现 Entry自己定义 总结一下就是各种pre 和 next指针的变换
public class LruCache01<K,V> {
private final int MAX_CACHE_SIZE;
private Entry first;
private Entry last;
private HashMap<K, Entry<K,V>> hashMap;
public LruCache01(int MAX_CACHE_SIZE) {
this.MAX_CACHE_SIZE = MAX_CACHE_SIZE;
hashMap=new HashMap<>();
}
public void put(K key, V value){
Entry entry = getEntry(key);
if(entry==null){
if(hashMap.size()>=MAX_CACHE_SIZE){
hashMap.remove(last.key);
//removeLast
removeLast();
}
entry=new Entry();
entry.key=key;
}
entry.value=value;
moveToFirst(entry);
hashMap.put(key,entry);
}
public V get(K key){
Entry entry = getEntry(key);
if(entry==null)
return null;
moveToFirst(entry);
return (V) entry.value;
}
public void remove(K key){
Entry entry = getEntry(key);
if(entry!=null){
if(entry.pre!=null)
entry.pre.next=entry.next;
if(entry.next!=null)
entry.next.pre=entry.pre;
if(entry==first)
first=entry.next;
if(entry==last)
last=entry.pre;
}
hashMap.remove(key);
}
public void moveToFirst(Entry entry){
if(entry==first)
return;
if(entry.pre!=null)
entry.pre.next=entry.next;
if(entry.next!=null)
entry.next.pre=entry.pre;
if(entry==last)
last=last.pre;
if(first==null || last==null){
first=last=entry;
return;
}
entry.next=first;
first.pre=entry;
first=entry;
entry.pre=null;
}
public void removeLast(){
if(last!=null){
last=last.pre;
if(last==null)
first=null;
else
last.next=null;
}
}
public Entry<K,V> getEntry(K key){
return hashMap.get(key);
}
@Override
public String toString(){
StringBuilder sb= new StringBuilder();
Entry entry = first;
while(entry!=null){
sb.append(String.format("%s:%s",entry.key,entry.value));
entry=entry.next;
}
return sb.toString();
}
}
class Entry<K,V>{
public Entry pre;
public Entry next;
public K key;
public V value;
}
LinkedHashMap的FIFO实现
只需要重新removeEldestEntry方法可以实现FIFO缓存
final int cacheSize=5;
LinkedHashMap<Integer,String> lru = new LinkedHashMap<Integer,String>(){
@Override
protected boolean removeEldestEntry(Map.Entry<Integer,String> eldest){
return size()>cacheSize;}
}
LRU 实现缓存的更多相关文章
- LRU算法 缓存淘汰策略
四种实现方式 LRU 1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也 ...
- Go -- LRU算法(缓存淘汰算法)(转)
1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. ...
- 【面试题】LRU算法及编码实现LRU策略缓存
概念 LRU(least recently used)就是将最近不被访问的数据给淘汰掉,LRU基于一种假设:认为最近使用过的数据将来被使用的概率也大,最近没有被访问的数据将来被使用的概率比较低. 原理 ...
- LeetCode题解: LRU Cache 缓存设计
LeetCode题解: LRU Cache 缓存设计 2014年12月10日 08:54:16 邴越 阅读数 1101更多 分类专栏: LeetCode 版权声明:本文为博主原创文章,遵循CC 4 ...
- mybatis PageHelper分页插件 和 LRU算法缓存读取数据
分页: PageHelper的优点是,分页和Mapper.xml完全解耦.实现方式是以插件的形式,对Mybatis执行的流程进行了强化,添加了总数count和limit查询.属于物理分页. 一.首先注 ...
- 重学数据结构(三)——使用单链表实现LRU淘汰缓存机制
使用单链表实现LRU(Least Recently Used)淘汰缓存机制 需求:存在一个单链表,在单链表尾部的都是越早之前添加的元素. 当元素被访问到时,会添加进缓存(也就是这个单链表中). 如果这 ...
- 借助LinkedHashMap实现基于LRU算法缓存
一.LRU算法介绍 LRU(Least Recently Used)最近最少使用算法,是用在操作系统中的页面置换算法,因为内存空间是有限的,不可能把所有东西都放进来,所以就必须要有所取舍,我们应该把什 ...
- 浅析LRU(K-V)缓存
LRU(Least Recently Used)算法是缓存技术中的一种常见思想,顾名思义,最近最少使用,也就是说有两个维度来衡量,一个是时间(最近),一个频率(最少).如果需要按优先级来对缓存中的K- ...
- 10行Java代码实现最近被使用(LRU)缓存
在最近的面试中,我曾被多次问到,怎么实现一个最近最少使用(LRU)的缓存.缓存可以通过哈希表来实现,然而为这个缓存增加大小限制会变成另一个有意思的问题.现在我们看一下怎么实现. 最近最少使用缓存的回收 ...
随机推荐
- C#之事件与eventArgs
static void Main(string[] args) { MyText myText = new MyText(); myTe ...
- linux上面sqlserver数据库的操作
sqlserver2017可以安装到linux也不是什么新鲜事, centos安装好sqlserver后有一写操作 systemctl status mssql-server:查看sqlserver的 ...
- Oracle篇 之 子查询
子查询:先执行内部再外部 Select last_name,salary,dept_id From s_emp Where dept_id in ( Select dept_id From s_emp ...
- NSParagraphStyle 的属性
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 20, 20)]; label.font = [UIFont sys ...
- 五一培训 清北学堂 DAY1
今天是冯哲老师的讲授~ 1.枚举 枚举也称作穷举,指的是从问题所有可能的解的集合中一一枚举各元素. 用题目中给定的检验条件判定哪些是无用的,哪些是有用的.能使命题成立的即为其解. 例一一棵苹果树上有n ...
- 单元测试报错NoSuchBeanDefinitionException
问题 在SpringBoot项目开发时,使用单元测试来运行一个Service,发现调用的一个Bean就是找不到,报错为: org.springframework.beans.factory.NoSuc ...
- Docker 命令查询
Docker — 从入门到实践 Docker 命令查询 基本语法 Docker 命令有两大类,客户端命令和服务端命令.前者是主要的操作接口,后者用来启动 Docker Daemon. 客户端命令:基本 ...
- foreach 中获取索引index的方法
一样,很少用到,记下来先 主要代码: foreach (var item in arr) { int index = arr.indexOf(item); //index 为索引值 }
- Codeforces Global Round 1 A~F
失踪人口回来写题了.. 写了几乎一下午.贴一贴代码以及口糊一下. A. 题意:计算一下这个多项式的和. 题解:暴力算一算对每一项异或一下. #include<bits/stdc++.h> ...
- ubuntu18.04安装mysql
ubuntu18.04中,默认情况下mysql默认包含在apt软件存储库中,要安装它只需要更新服务器上的包索引并安装默认包apt-get. 1.安装mysql sudo apt-get update ...