阿里巴巴笔试考到了LRU,一激动忘了怎么回事了。。准备不充分啊。。

缓存这个东西就是为了提高运行速度的,由于缓存是在寸土寸金的内存里面,不是在硬盘里面,所以容量是很有限的。LRU这个算法就是把最近一次使用时间离现在时间最远的数据删除掉。先说说List:每次访问一个元素后把这个元素放在 List一端,这样一来最远使用的元素自然就被放到List的另一端。缓存满了t的时候就把那最远使用的元素remove掉。但更实用的是HashMap。因为List太慢,要删掉的数据总是位于List底层数组的第一个位置,删掉之后,后面的数据要向前补位。。所以复杂度是O(n),那就用链表结构的LinkedHashMap呗~,LinkedHashMap默认的元素顺序是put的顺序,但是如果使用带参数的构造函数,那么LinkedHashMap会根据访问顺序来调整内部 顺序。 LinkedHashMap的get()方法除了返回元素之外还可以把被访问的元素放到链表的底端,这样一来每次顶端的元素就是remove的元素。

构造函数如下:

public LinkedHashMap (int initialCapacity, float loadFactor, boolean accessOrder);

initialCapacity   初始容量

loadFactor    加载因子,一般是 0.75f

accessOrder   false 基于插入顺序  true  基于访问顺序(get一个元素后,这个元素被加到最后,使用了LRU  最近最少被使用的调度算法)

来个例子吧:
import java.util.*;

class Test
{
public static void main(String[] args) throws Exception{ Map<Integer,Integer> map=new LinkedHashMap<>(10,0.75f,true);
map.put(9,3);
map.put(7,4);
map.put(5,9);
map.put(3,4);
//现在遍历的话顺序肯定是9,7,5,3
//下面访问了一下9,3这个键值对,输出顺序就变喽~
map.get(9);
for(Iterator<Map.Entry<Integer,Integer>> it=map.entrySet().iterator();it.hasNext();){
System.out.println(it.next().getKey());
}
}
}

输出

7
5
3
9
好玩吧~
下面开始实现LRU缓存喽~
import java.util.*;
//扩展一下LinkedHashMap这个类,让他实现LRU算法
class LRULinkedHashMap<K,V> extends LinkedHashMap<K,V>{
//定义缓存的容量
private int capacity;
private static final long serialVersionUID = 1L;
//带参数的构造器
LRULinkedHashMap(int capacity){
//调用LinkedHashMap的构造器,传入以下参数
super(16,0.75f,true);
//传入指定的缓存最大容量
this.capacity=capacity;
}
//实现LRU的关键方法,如果map里面的元素个数大于了缓存最大容量,则删除链表的顶端元素
@Override
public boolean removeEldestEntry(Map.Entry<K, V> eldest){
System.out.println(eldest.getKey() + "=" + eldest.getValue());
return size()>capacity;
}
}
//测试类
class Test{
public static void main(String[] args) throws Exception{ //指定缓存最大容量为4
Map<Integer,Integer> map=new LRULinkedHashMap<>(4);
map.put(9,3);
map.put(7,4);
map.put(5,9);
map.put(3,4);
map.put(6,6);
//总共put了5个元素,超过了指定的缓存最大容量
//遍历结果
for(Iterator<Map.Entry<Integer,Integer>> it=map.entrySet().iterator();it.hasNext();){
System.out.println(it.next().getKey());
}
}
}

输出结果如下

9=3
9=3
9=3
9=3
9=3
7
5
3
6
分析一下:使用带参数构造器,且启用LRU模式的LinkedHashMap会在每次有新元素加入的时候,判断当前储存元素是否超过了缓存上限,也就是执行
一次removeEldestEntry方法,看最后的遍历结果,发现果然把9删除了,LRU发挥作用了~

如何用LinkedHashMap实现LRU缓存算法的更多相关文章

  1. LinkedHashMap实现LRU缓存算法

    LinkedHashMap的get()方法除了返回元素之外还可以把被访问的元素放到链表的底端,这样一来每次顶端的元素就是remove的元素. 构造函数如下: public LinkedHashMap  ...

  2. 总是套路留人心, JAVA提供的套路: LinkedHashMap实现LRU缓存; InvocationHandler实现动态代理; fork/join实现窃取算法

    1. LinkedHashMap实现LRU缓存 LRU缓存核心是根据访问顺序排序, 自动移除队尾缓存, LinkedHashMap已经实现了这些要求: public LRUCache<K, V& ...

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

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

  4. LinkedHashMap 实现LRU缓存

    date: 2020-07-09 13:52:00 updated: 2020-07-21 17:40:00 LinkedHashMap 实现LRU缓存 参考 LinkedHashMap是HashMa ...

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

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

  6. HashMap+双向链表手写LRU缓存算法/页面置换算法

    import java.util.Hashtable; class DLinkedList { String key; //键 int value; //值 DLinkedList pre; //双向 ...

  7. come on! 基于LinkedHashMap实现LRU缓存

    /** * @Description 基于LinkedHashMap实现一个基于'LRU最近最少使用'算法的缓存,并且最多存MAX个值 * @Author afei * @date:2021/4/25 ...

  8. LRU缓存算法与pylru

    这篇写的略为纠结,算法原理.库都是现成的,我就调用了几个函数而已,这有啥好写的?不过想了想,还是可以介绍一下LRU算法的原理及简单的用法.   LRU(Least Recently Used,最近最少 ...

  9. Java 自定义实现 LRU 缓存算法

    背景 LinkedHashMap继承自HashMap,内部提供了一个removeEldestEntry方法,该方法正是实现LRU策略的关键所在,且HashMap内部专门为LinkedHashMap提供 ...

随机推荐

  1. json 的 使用方法以及与数组的区别

    JSON简介,全称是JavaScript Object Notation.它是基于JavaScript编程语言ECMA-262 3rd Edition-December 1999标准的一种轻量级的数据 ...

  2. select,poll,epoll之api笔记

    参考:http://www.cnblogs.com/Anker/p/3265058.html select /* According to POSIX.1-2001 */ #include <s ...

  3. 11.java.lang.ArrayStoreException

    java.lang.ArrayStoreException 数组存储异常 当试图将类型不兼容类型的对象存入一个Object[]数组时将引发异常 Object[] obj = new String[3] ...

  4. 一款C++静态分析工具 —— CppDepend

    Wrote by mutouyun. (http://darkc.at/cppdepend/) 去年6月份的时候,CppDepend的一位技术社区经理(technical community mana ...

  5. 清风注解-Swift程序设计语言:Point11~15

    目录索引 清风注解-Swift程序设计语言 Point 11. 数值型字面量 代码事例: let decimalInteger = // 十进制的17 let binaryInteger = 0b10 ...

  6. City Game(动态规划)

    City Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  7. Tcl学习之--语法|变量

    [语法|变量] l 脚本.命令和单词 Tcl提供了大约100条命令.Tk提供了另外几十条,脚本包括一条或多条,通过换行符或分号分隔开. set a 12 set b 23 也能够写成一行: set a ...

  8. android UI进阶之style和theme的使用

    今天来和大家分享一下android中UI设计里面常会用到的style和theme. 首先,style和theme都是资源,android提供了很多这样的默认资源.你可以来使用它们.同时你也可以自己定义 ...

  9. 权威指南之脚本化http

    使用javascript代码操作http是可行的.当用脚本设置window对象的location属性或调用表单对象的submit方法时,都会初始化http请求.这两种情况下,浏览器会加载新页面. aj ...

  10. 【asp.net】将GridView数据导出Excel

    概要: 中午睡了一会,醒来的时候看到老师叫我去办公室,需求是这样的,把excel表中的每个同学,判断图片目录中是否有对应的照片(图片的名字用的学号或身份证号码) 没有对应图片的学生记录,存入自己的数据 ...