利用LinkedHashMap实现LRU
LRU:Least recently used, 最近最少使用,一般在设计缓存中间件时常用到该原则。
设计缓存时需要考虑以下几点:
1,为了快速获取缓存数据,考虑使用哈希表;
2,为了达到LRU的目的,需要保证数据有序,这又和哈希表产生冲突。
链表能达到有序的目的,但是检索慢;哈希表检索快,但是无序。
Java提供的LinkedHashMap恰好具备这两个特性,LinkedHashMap是HashMap的子类,在完全继承HashMap的哈希特性之外,还具有双向链表的数据结构,以保证数据的顺序。
文章图片
图片来源于https://blog.csdn.net/justloveyou_/article/details/71713781 每个put进来的Entry既要放到哈希表中对应的位置,也要将其插入双向链表的尾部。所以LinkedHashMap中的Entry数据结构相比HashMap,除了hash、key、value、next属性之外,还有before、after属性用于维护LinkedHashMap的双向链表。
文章图片
图片来源于https://blog.csdn.net/justloveyou_/article/details/71713781 【利用LinkedHashMap实现LRU】accessOrder:LinkedHashMap中一个重要的成员变量,boolean类型,有相应的构造方法。true表示按照访问顺序迭代,false时表示按照插入顺序迭代。如果我们想要达到LRU的效果,在构造LinkedHashMap时,accessOrder就应该赋值true。
removeEldestEntry:LinkedHashMap中一个重要的方法,默认返回false,表示是否删除最旧的元素,如果要实现LUR,就要override该方法,告诉LinkedHashMap什么情况下删除旧元素,譬如,当整个LinkedHashMap的size达到设定的阈值,需要删除旧元素。
代码:
import java.util.LinkedHashMap;
import java.util.Map;
public LRUCache extends LinkedHashMap {
private int cacheSize;
public LRUCache(int cacheSize) {
super(16, 0.75, true);
//accessOrder设置为true,表示按照访问顺序迭代
this.cacheSize = cacheSize;
}//覆盖方法,当LinkedHashMap的size达到缓存阈值时,删除旧元素
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() >= cacheSize;
}
}
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树
- 人脸识别|【人脸识别系列】| 实现自动化妆
- paddle|动手从头实现LSTM
- pytorch|使用pytorch从头实现多层LSTM