LRU缓存简单实现
缓存接口定义
/**
* 缓存接口
*
* @author zhi
*
*/
public interface ICache<K, V> {
/**
* 添加缓存数据
*
* @param key
* @param value
*/
void put(K key, V value); /**
* 获取缓存数据
*
* @param key
* @return
*/
V get(K key); /**
* 删除缓存数据
*
* @param key
* @return
*/
V remove(K key); /**
* 清除缓存
*/
void clear();
}
利用LinkedHashMap实现
import java.util.LinkedHashMap;
import java.util.Map; public class LRUCache<K, V> implements ICache<K, V> {
private Map<K, V> map = null; @SuppressWarnings("serial")
public LRUCache(final int maxCapacity) {
map = new LinkedHashMap<K, V>(maxCapacity, 0.75f, true) {
@Override
protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
return size() > maxCapacity;
}
};
} @Override
public V get(K key) {
return map.get(key);
} @Override
public synchronized void put(K key, V value) {
map.put(key, value);
} @Override
public V remove(K key) {
return map.remove(key);
} @Override
public void clear() {
map.clear();
}
}
利用双链表实现
import java.util.HashMap;
public class LRUCache<K, V> implements ICache<K, V> {
private final int maxCapacity;
private CacheItem first;
private CacheItem last;
private HashMap<K, CacheItem> cache;
public LRUCache(final int maxCapacity) {
this.maxCapacity = maxCapacity;
cache = new HashMap<K, CacheItem>(maxCapacity);
}
@Override
public V get(K key) {
CacheItem item = cache.get(key);
if (item == null) {
return null;
}
moveToFirst(item);
return item.value;
}
@Override
public synchronized void put(K key, V value) {
CacheItem item = cache.get(key);
if (item != null) {
item.value = value;
moveToFirst(item);
} else {
if (cache.size() == maxCapacity) {
cache.remove(last.key);
last = last.pre;
if (last == null) {
first = null;
} else {
last.next = null;
}
}
item = new CacheItem(key, value);
cache.put(key, item);
if (first != null) {
item.next = first;
first.pre = item;
}
first = item;
if (last == null) {
last = item;
}
}
}
@Override
public V remove(K key) {
if (cache.containsKey(key)) {
CacheItem item = cache.get(key);
if (item.pre != null) {
item.pre.next = item.next;
}
if (item.next != null) {
item.next.pre = item.pre;
}
if (item == first) {
first = item.next;
}
if (item == last) {
last = item.pre;
}
return cache.remove(key).value;
} else {
return null;
}
}
private void moveToFirst(CacheItem item) {
if (item == first) {
return;
}
if (item.next == null) {
last = item.pre;
}
item.pre.next = item.next;
item.next = first;
first = item;
first.pre = null;
}
@Override
public void clear() {
first = last = null;
cache.clear();
}
class CacheItem {
CacheItem pre;
CacheItem next;
K key;
V value;
public CacheItem(K key, V value) {
this.key = key;
this.value = value;
}
}
}
LRU缓存简单实现的更多相关文章
- LRU缓存实现(Java)
LRU Cache的LinkedHashMap实现 LRU Cache的链表+HashMap实现 LinkedHashMap的FIFO实现 调用示例 LRU是Least Recently Used 的 ...
- 面试挂在了 LRU 缓存算法设计上
好吧,有人可能觉得我标题党了,但我想告诉你们的是,前阵子面试确实挂在了 RLU 缓存算法的设计上了.当时做题的时候,自己想的太多了,感觉设计一个 LRU(Least recently used) 缓存 ...
- Java集合详解5:深入理解LinkedHashMap和LRU缓存
今天我们来深入探索一下LinkedHashMap的底层原理,并且使用linkedhashmap来实现LRU缓存. 摘要: HashMap和双向链表合二为一即是LinkedHashMap.所谓Linke ...
- 04 | 链表(上):如何实现LRU缓存淘汰算法?
今天我们来聊聊“链表(Linked list)”这个数据结构.学习链表有什么用呢?为了回答这个问题,我们先来讨论一个经典的链表应用场景,那就是+LRU+缓存淘汰算法. 缓存是一种提高数据读取性能的技术 ...
- LRU缓存原理
LRU(Least Recently Used) LRU是近期最少使用的算法,它的核心思想是当缓存满时,会优先淘汰那些近期最少使用的缓存对象. 采用LRU算法的缓存有两种:LrhCache和DisL ...
- 链表(上):如何实现LRU缓存淘汰算法?
一.什么是链表 和数组一样,链表也是一种线性表. 从内存结构来看,链表的内存结构是不连续的内存空间,是将一组零散的内存块串联起来,从而进行数据存储的数据结构. 链表中的每一个内存块被称为节点Node. ...
- [转]LRU缓存实现(Java)
LRU Cache的LinkedHashMap实现 LRU Cache的链表+HashMap实现 LinkedHashMap的FIFO实现 调用示例 LRU是Least Recently Used 的 ...
- 请用Java设计一个Least Recently Used (LRU) 缓存
LRU介绍:LRU是Least Recently Used的缩写,即最少使用页面置换算法,是为虚拟页式存储管理服务的, 思路介绍: 能够使用两个标准的数据结构来实现.Map和Queue.由于须要支持多 ...
- 链表:如何实现LRU缓存淘汰算法?
缓存淘汰策略: FIFO:先入先出策略 LFU:最少使用策略 LRU:最近最少使用策略 链表的数据结构: 可以看到,数组需要连续的内存空间,当内存空间充足但不连续时,也会申请失败触发GC,链表则可 ...
随机推荐
- Python基础15
P75. 闭包,需再理解. 装饰器,语法糖
- 关于VS C++中项目属性的一些名称的含义
这个属性页(Alt + F7)界面下的$开头的内容的含义 $(Platform), X64或X86类似的. $(SolutionDir),.sln的位置 $(Configuration), Debug ...
- ASP.NET Core使用EPPlus导入导出Excel
开发过程中,经常会遇到导入导出数据的需求,本篇博客介绍在.NET Core中如何使用EPPlus组件导入导出Excel EPPlus: EPPlus是使用Open Office XML格式(xlsx) ...
- selenium控制超链接在当前标签页中打开或重新打开一个标签页
selenium控制超链接在当前标签页中打开或重新打开一个标签页 在web页面源码中,控制超链接的打开是在当前标签页还是重新打开一个标签页,是由属性target=“_black”进行控制的.如果还有属 ...
- vue+element下拉框样式的点击按钮
项目中点击按钮实在太多了,怎么办呢?我们就可以将它们制作成像下拉框那样的类似操作 1.HTML样式部分:关键点在于command 方法和属性 1 <el-dropdown 2 size=&quo ...
- 有些CRM settype用事务码COMM_ATTRSET打不开的原因
This question is asked by Dr. Lin. Issue For example, settype COM_COMMERCIAL could be opened via tco ...
- 解决securecrt连接慢(而xshell秒连)的问题
打开securecrt的跟踪选项,观察输出信息来诊断 解决方法: 1)首先,将全局设置中,GSSAPI属性由自动改为GSSAPI 2)其次,将不支持的多余的密钥交换去掉 3)最后,可以将服务端 ...
- Linux系统运行模式介绍
Linux运行模式 自由服务,即不需要用户独立去安装的软件服务,而是在系统安装好之后就可以直接使用的服务(内置服务). 运行模式也称为运行级别,属于linux的自有服务. 运行模式可以理解为一旦你开机 ...
- Shiro RememberMe 1.2.4 反序列化漏洞详细复现
0x00 前言 今天上班的时候收到了一个复测的任务,打开一看,shiro反序列化漏洞,What?这是个什么东西,经百度查找后才知道,原来是Java的开发框架,好吧,还是没听说过..由于初测报告上的过程 ...
- 子网掩码的作用与IP网段的划分
公有IP地址分类 A类:1.0.0.0 到 127.255.255.255主要分配 给大量主机而局域网网络数量较少的大型网络 B类:128.0.0.0 到191.255.255.255 一般用于国际性 ...