缓存接口定义

/**
* 缓存接口
*
* @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缓存简单实现的更多相关文章

  1. LRU缓存实现(Java)

    LRU Cache的LinkedHashMap实现 LRU Cache的链表+HashMap实现 LinkedHashMap的FIFO实现 调用示例 LRU是Least Recently Used 的 ...

  2. 面试挂在了 LRU 缓存算法设计上

    好吧,有人可能觉得我标题党了,但我想告诉你们的是,前阵子面试确实挂在了 RLU 缓存算法的设计上了.当时做题的时候,自己想的太多了,感觉设计一个 LRU(Least recently used) 缓存 ...

  3. Java集合详解5:深入理解LinkedHashMap和LRU缓存

    今天我们来深入探索一下LinkedHashMap的底层原理,并且使用linkedhashmap来实现LRU缓存. 摘要: HashMap和双向链表合二为一即是LinkedHashMap.所谓Linke ...

  4. 04 | 链表(上):如何实现LRU缓存淘汰算法?

    今天我们来聊聊“链表(Linked list)”这个数据结构.学习链表有什么用呢?为了回答这个问题,我们先来讨论一个经典的链表应用场景,那就是+LRU+缓存淘汰算法. 缓存是一种提高数据读取性能的技术 ...

  5. LRU缓存原理

    LRU(Least Recently Used)  LRU是近期最少使用的算法,它的核心思想是当缓存满时,会优先淘汰那些近期最少使用的缓存对象. 采用LRU算法的缓存有两种:LrhCache和DisL ...

  6. 链表(上):如何实现LRU缓存淘汰算法?

    一.什么是链表 和数组一样,链表也是一种线性表. 从内存结构来看,链表的内存结构是不连续的内存空间,是将一组零散的内存块串联起来,从而进行数据存储的数据结构. 链表中的每一个内存块被称为节点Node. ...

  7. [转]LRU缓存实现(Java)

    LRU Cache的LinkedHashMap实现 LRU Cache的链表+HashMap实现 LinkedHashMap的FIFO实现 调用示例 LRU是Least Recently Used 的 ...

  8. 请用Java设计一个Least Recently Used (LRU) 缓存

    LRU介绍:LRU是Least Recently Used的缩写,即最少使用页面置换算法,是为虚拟页式存储管理服务的, 思路介绍: 能够使用两个标准的数据结构来实现.Map和Queue.由于须要支持多 ...

  9. 链表:如何实现LRU缓存淘汰算法?

    缓存淘汰策略: FIFO:先入先出策略 LFU:最少使用策略 LRU:最近最少使用策略   链表的数据结构: 可以看到,数组需要连续的内存空间,当内存空间充足但不连续时,也会申请失败触发GC,链表则可 ...

随机推荐

  1. iviewUI 前端静态页面实现增删改查分页

    完整代码部分 (仅供参考哈): <template> <div> <label prop="name"> 姓名: </label> ...

  2. Natasha V1.3.6.0 的升级日志

    开源库满足于个人,而完善于大众. Natasha 自稳定版发布之后,众多老铁参与增强改进,感谢如下老铁的反馈: 1. 异常搜集 在 wenjq0911 建议下,添加了异常捕获,现 Natasha 的编 ...

  3. oracle中如何生成awr【性能调优】报告

    1.进入数据库 sqlplus / as sysdba 2.查看用户 show parameter db_name 3.开始压测后执行 exec DBMS_WORKLOAD_REPOSITORY.CR ...

  4. Matplotlib 绘图与可视化 一些控件的介绍和属性,反正就是乱七八糟的

    这个链接里有下面这个图(图里还有超链接):https://matplotlib.org/3.1.1/api/artist_api.html#matplotlib.artist.Artist 各种图例: ...

  5. ES6-面向对象

    1.老版的面向对象: function User(name,pass){ this.name=name; this.pass=pass; } User.prototype.showName=funct ...

  6. 百度地图API操作实战

    什么是百度地图API: 百度地图API是为开发者免费提供的一套基于百度地图服务的应用接口,包括JavaScript API,web服务API,Android等多种开发工具服务.提供基本地图展现,搜索, ...

  7. 【转】解决Oracle 11g在用EXP导出时,空表不能导出

    一.问题原因: 11G中有个新特性,当表无数据时,不分配segment,以节省空间 .insert一行,再rollback就产生segment了. 该方法是在在空表中插入数据,再删除,则产生segme ...

  8. Oracle 数据库修复一例

    Oracle 数据库修复一例:(系统装有两个实例,分别是:bhorcl,orcl)今天一台生产服务器的Oracle不能正常登录,用plSql登录,提示:TNS:listernet does noet ...

  9. Jmeter 在 beanshell 脚本中写日志

    JMETER 在执行时,会写日志数据,我们在编写脚本的时候也可以自己写日志. 日志记录再jmeter 的bin 目录的 jmeter.log 文件中. jmeter 比较人性化,它在这里提供了脚本可以 ...

  10. elastalert docker安装

    基于对elasticsearch中数据监控需要,我尝试了sentinl和elastalert两款工具.虽然elastalert是纯文本,但易配置管理.elk自带的watch需要付费才可使用. 6.2x ...