Java实现LRU算法
一。LRU算法简介
LRU(Least Recently Used)最近最久未使用算法
常见应用场景:内存管理中的页面置换算法、缓存淘汰中的淘汰策略等
二。实现理论
底层结构:双向链表 + HashMap ,双向链表由特定的哈希节点组成。
package com.xl.Base; import java.util.HashMap;
import java.util.Iterator; /**
* 最近最久未使用淘汰策略
* 基于 双向链表 + 哈希表组成,其中双向链表由哈希链表节点构成
* 封装为 LRU(K, V)
* 对外提供 get(K)访问数据、put(K, V)更新数据、Iterator()遍历数据
*/
public class LRU<K, V> implements Iterable<K>{ private Node head;
private Node tail;
//记录K-Node映射,便于快速查找目标数据对应节点
private HashMap<K, Node> map;
private int maxSize; //哈希链表节点类 Node
private class Node{
Node pre;
Node next;
K k;
V v; //Node对外提供构造方法
public Node(K k, V v) {
this.k = k;
this.v = v;
}
} //初始化时必须传入最大可用内存容量
public LRU(int maxSize){
this.maxSize = maxSize;
//HashMap初始容量设置为 maxSize * 4/3,即达到最大可用内存时,HashMap也不会自动扩容浪费空间
this.map = new HashMap<>(maxSize * 4 / 3); head.next = tail;
tail.pre = head;
} //获取指定数据
private V get(K key) {
//判断是否存在对应数据
if(!map.containsKey(key)) {
return null;
} //最新访问的数据移动到链表头
Node node = map.get(key);
remove(node);
addFirst(node);
return node.v;
} //更新旧数据或添加数据
private void put(K key, V value) {
//若存在旧数据则删除
if(map.containsKey(key)) {
Node node = map.get(key);
remove(node);
} //新数据对应节点插入链表头
Node node = new Node(key, value);
map.put(key, node);
addFirst(node); //判断是否需要淘汰数据
if(map.size() > maxSize) {
removeLast();
//数据节点淘汰后,同时删除map中的映射
map.remove(node.k);
}
} //将指定节点插入链表头
private void addFirst(Node node) {
Node next = head.next; head.next = node;
node.pre = head; node.next = next;
next.pre = node;
} //从链表中删除指定节点
private void remove(Node node) {
Node pre = node.pre;
Node next = node.next; pre.next = next;
next.pre = pre; node.next = null;
node.pre = null;
} //淘汰数据
private Node removeLast() {
//找到最近最久未使用的数据所对应节点
Node node = tail.pre; //淘汰该节点
remove(node); return node;
} //通过迭代器遍历所有数据对应键
@Override
public Iterator<K> iterator() {
return new Iterator<K>() { private Node cur = head.next; @Override
public boolean hasNext() {
return cur != tail;
} @Override
public K next() {
Node node = cur;
cur = cur.next;
return node.k;
} };
} }
Java实现LRU算法的更多相关文章
- Redis 笔记整理:回收策略与 LRU 算法
Redis的回收策略 noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外) allkeys-lru: 尝试回收最少使用的键(L ...
- LRU算法的Java实现
LRU全称是Least Recently Used,即最近最久未使用的意思. LRU算法的设计原则是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小.也就是说,当限定的空间已 ...
- 使用java.util.LinkedList模拟实现内存页面置换算法--LRU算法
一,LRU算法介绍 LRU是内存分配中“离散分配方式”之分页存储管理方式中用到的一个算法.每个进程都有自己的页表,进程只将自己的一部分页面加载到内存的物理块中,当进程在运行过程中,发现某页面不在物理内 ...
- LRU算法介绍和在JAVA的实现及源码分析
一.写随笔的原因:最近准备去朋友公司面试,他说让我看一下LRU算法,就此整理一下,方便以后的复习. 二.具体的内容: 1.简介: LRU是Least Recently Used的缩写,即最近最少使用. ...
- 近期最久未使用页面淘汰算法———LRU算法(java实现)
请珍惜小编劳动成果,该文章为小编原创,转载请注明出处. LRU算法,即Last Recently Used ---选择最后一次訪问时间距离当前时间最长的一页并淘汰之--即淘汰最长时间没有使用的页 依照 ...
- 最近最久未使用页面淘汰算法———LRU算法(java实现)
请珍惜小编劳动成果,该文章为小编原创,转载请注明出处. LRU算法,即Last Recently Used ---选择最后一次访问时间距离当前时间最长的一页并淘汰之--即淘汰最长时间没有使用的页 按照 ...
- Android图片缓存之Lru算法
前言: 上篇我们总结了Bitmap的处理,同时对比了各种处理的效率以及对内存占用大小.我们得知一个应用如果使用大量图片就会导致OOM(out of memory),那该如何处理才能近可能的降低oom发 ...
- 缓存淘汰算法--LRU算法
1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是"如果数据最近被访问过,那么将来被访问的几率也 ...
- 借助LinkedHashMap实现基于LRU算法缓存
一.LRU算法介绍 LRU(Least Recently Used)最近最少使用算法,是用在操作系统中的页面置换算法,因为内存空间是有限的,不可能把所有东西都放进来,所以就必须要有所取舍,我们应该把什 ...
随机推荐
- 模拟QQ窗口抖动效果(通过MoveWindow和Sleep进行模拟)
RECT rtWindow; GetWindowRect(&rtWindow); //long x = 400; //long y = 200; long x = rtWindow.left; ...
- Win8Metro(C#)数字图像处理--2.23二值图像开运算
原文:Win8Metro(C#)数字图像处理--2.23二值图像开运算 [函数名称] 二值图像开运算函数OpenOperateProcess(WriteableBitmap src) [算法说明 ...
- GlusterFS集群文件系统研究(负载均衡的最常用办法) good
http://blog.csdn.net/liuaigui/article/details/6284551 http://blog.csdn.net/liuaigui/article/details/ ...
- 微信小程序把玩(三十三)Record API
原文:微信小程序把玩(三十三)Record API 其实这个API也挺奇葩的,录音结束后success不走,complete不走,fail也不走, 不知道是不是因为电脑测试的原因,只能等公测或者等他们 ...
- 类选择器和所作用的标签一起写为什么不起作用? - CSDN博客
原文:类选择器和所作用的标签一起写为什么不起作用? - CSDN博客 HTML代码: css样式: 这不是将样式作用于circle类下的有current类的li标签吗?为什么不起作用? 原因: 选择器 ...
- 了解BroadcastRecever
广播分类: 标准广播(Normal broadcasts):完全异步执行的广播,接收没有先后顺序,效率高,无法被接收器被拦截. 有序广播(Ordered broadcasts) :同步执行的广播,有先 ...
- 解析 Qt 字库移植并能显示中文 (上篇)
原文http://mobile.51cto.com/symbian-272552.htm 本文介绍的是Qt 字库移植并能显示中文,需要的字体库文件,一般是多个.具体移植那一个,看你使用的字库是什么了, ...
- 通过使用URLEncoder与URLDecoder进行编码和解码
使用改方法必须导入 java.net包 <%@page import="java.net.*" %> 编码: 当要存储或者发送数据的时候使用,将编码后的字符串再发送或者 ...
- 使用 acl_cpp 的 HttpServlet 类及服务器框架编写WEB服务器程序(系列文章)
在 <用C++实现类似于JAVA HttpServlet 的编程接口 > 文章中讲了如何用 HttpServlet 等相关类编写 CGI 程序,于是有网友提出了 CGI 程序低效性,不错, ...
- Spring Boot的学习之路(02):和你一起阅读Spring Boot官网
官网是我们学习的第一手资料,我们不能忽视它.却往往因为是英文版的,我们选择了逃避它,打开了又关闭. 我们平常开发学习中,很少去官网上看.也许学完以后,我们连官网长什么样子,都不是很清楚.所以,我们在开 ...