LRU:Least Recently used 最近最少使用

1.使用LinkedHashMap实现 inheritance实现方式 继承map类 可以使用Collections.synchronizedMap方式实现线程安全的操作

  1. public class LruCache<K,V> extends LinkedHashMap<K,V> {
  2. private final int MAX_CACHE_SIZE;
  3. public LruCache(int cacheSize) {
  4. super((int)Math.ceil(cacheSize/0.75)+1,0.75f,true );
  5. MAX_CACHE_SIZE = cacheSize;
  6. }
  7. @Override
  8. protected boolean removeEldestEntry(Map.Entry eldest){
  9. return size()> MAX_CACHE_SIZE;
  10. }
  11.  
  12. @Override
  13. public String toString(){
  14. StringBuilder sb= new StringBuilder();
  15. for(Map.Entry<K,V> entry : entrySet()){
  16. sb.append(String.format("%s:%s",entry.getKey(),entry.getValue()));
  17. }
  18. return sb.toString();
  19. }
  20. }

2、LinkedHashMap 使用delegation方式实现

没有map接口

  1. public class LruByDelegation<K,V> {
  2.  
  3. private final int MAX_CACHE_SIZE;
  4. private final float DEFAULT_LOAD_FACTOR = 0.75f;
  5. LinkedHashMap<K,V> map;
  6.  
  7. public LruByDelegation(int cacheSize) {
  8. this.MAX_CACHE_SIZE = cacheSize;
  9.  
  10. int capacity = (int) (Math.ceil(MAX_CACHE_SIZE/DEFAULT_LOAD_FACTOR)+1);
  11. map= new LinkedHashMap(capacity,DEFAULT_LOAD_FACTOR,true){
  12. @Override
  13. protected boolean removeEldestEntry(Map.Entry eldest){
  14. return size()>MAX_CACHE_SIZE;
  15. }
  16. };
  17. }
  18.  
  19. public synchronized void put(K key,V value){
  20. map.put(key,value);
  21. }
  22.  
  23. public synchronized V get(K key){
  24. return map.get(key);
  25. }
  26. public synchronized void remove(K key){
  27. map.remove(key);
  28. }
  29. public synchronized Set<Map.Entry<K,V>> getAll(){
  30. return map.entrySet();
  31. }
  32. public synchronized int size(){
  33. return map.size();
  34. }
  35. public synchronized void clear(){
  36. map.clear();
  37. }
  38.  
  39. @Override
  40. public String toString(){
  41. StringBuilder sb= new StringBuilder();
  42. for(Map.Entry entry : map.entrySet()){
  43. sb.append(String.format("%s:%s",entry.getKey(),entry.getValue()));
  44. }
  45. return sb.toString();
  46. }
  47.  
  48. }

2 Cache链表+HashMap实现   Entry自己定义  总结一下就是各种pre 和 next指针的变换

  1. public class LruCache01<K,V> {
  2. private final int MAX_CACHE_SIZE;
  3. private Entry first;
  4. private Entry last;
  5. private HashMap<K, Entry<K,V>> hashMap;
  6.  
  7. public LruCache01(int MAX_CACHE_SIZE) {
  8. this.MAX_CACHE_SIZE = MAX_CACHE_SIZE;
  9. hashMap=new HashMap<>();
  10. }
  11. public void put(K key, V value){
  12. Entry entry = getEntry(key);
  13. if(entry==null){
  14. if(hashMap.size()>=MAX_CACHE_SIZE){
  15. hashMap.remove(last.key);
  16. //removeLast
  17. removeLast();
  18. }
  19. entry=new Entry();
  20. entry.key=key;
  21. }
  22. entry.value=value;
  23. moveToFirst(entry);
  24. hashMap.put(key,entry);
  25.  
  26. }
  27. public V get(K key){
  28. Entry entry = getEntry(key);
  29. if(entry==null)
  30. return null;
  31. moveToFirst(entry);
  32. return (V) entry.value;
  33. }
  34.  
  35. public void remove(K key){
  36. Entry entry = getEntry(key);
  37. if(entry!=null){
  38. if(entry.pre!=null)
  39. entry.pre.next=entry.next;
  40. if(entry.next!=null)
  41. entry.next.pre=entry.pre;
  42. if(entry==first)
  43. first=entry.next;
  44. if(entry==last)
  45. last=entry.pre;
  46. }
  47. hashMap.remove(key);
  48. }
  49. public void moveToFirst(Entry entry){
  50. if(entry==first)
  51. return;
  52. if(entry.pre!=null)
  53. entry.pre.next=entry.next;
  54. if(entry.next!=null)
  55. entry.next.pre=entry.pre;
  56. if(entry==last)
  57. last=last.pre;
  58. if(first==null || last==null){
  59. first=last=entry;
  60. return;
  61. }
  62. entry.next=first;
  63. first.pre=entry;
  64. first=entry;
  65. entry.pre=null;
  66. }
  67.  
  68. public void removeLast(){
  69. if(last!=null){
  70. last=last.pre;
  71. if(last==null)
  72. first=null;
  73. else
  74. last.next=null;
  75. }
  76. }
  77.  
  78. public Entry<K,V> getEntry(K key){
  79. return hashMap.get(key);
  80. }
  81.  
  82. @Override
  83. public String toString(){
  84. StringBuilder sb= new StringBuilder();
  85. Entry entry = first;
  86. while(entry!=null){
  87. sb.append(String.format("%s:%s",entry.key,entry.value));
  88. entry=entry.next;
  89. }
  90. return sb.toString();
  91. }
  92. }
  93. class Entry<K,V>{
  94. public Entry pre;
  95. public Entry next;
  96. public K key;
  97. public V value;
  98. }

LinkedHashMap的FIFO实现

只需要重新removeEldestEntry方法可以实现FIFO缓存

  1. final int cacheSize=5;
  2. LinkedHashMap<Integer,String> lru = new LinkedHashMap<Integer,String>(){
  3. @Override
  4. protected boolean removeEldestEntry(Map.Entry<Integer,String> eldest){
  5. return size()>cacheSize;}
  6. }

LRU 实现缓存的更多相关文章

  1. LRU算法 缓存淘汰策略

    四种实现方式 LRU 1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也 ...

  2. Go -- LRU算法(缓存淘汰算法)(转)

    1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. ...

  3. 【面试题】LRU算法及编码实现LRU策略缓存

    概念 LRU(least recently used)就是将最近不被访问的数据给淘汰掉,LRU基于一种假设:认为最近使用过的数据将来被使用的概率也大,最近没有被访问的数据将来被使用的概率比较低. 原理 ...

  4. LeetCode题解: LRU Cache 缓存设计

    LeetCode题解: LRU Cache 缓存设计 2014年12月10日 08:54:16 邴越 阅读数 1101更多 分类专栏: LeetCode   版权声明:本文为博主原创文章,遵循CC 4 ...

  5. mybatis PageHelper分页插件 和 LRU算法缓存读取数据

    分页: PageHelper的优点是,分页和Mapper.xml完全解耦.实现方式是以插件的形式,对Mybatis执行的流程进行了强化,添加了总数count和limit查询.属于物理分页. 一.首先注 ...

  6. 重学数据结构(三)——使用单链表实现LRU淘汰缓存机制

    使用单链表实现LRU(Least Recently Used)淘汰缓存机制 需求:存在一个单链表,在单链表尾部的都是越早之前添加的元素. 当元素被访问到时,会添加进缓存(也就是这个单链表中). 如果这 ...

  7. 借助LinkedHashMap实现基于LRU算法缓存

    一.LRU算法介绍 LRU(Least Recently Used)最近最少使用算法,是用在操作系统中的页面置换算法,因为内存空间是有限的,不可能把所有东西都放进来,所以就必须要有所取舍,我们应该把什 ...

  8. 浅析LRU(K-V)缓存

    LRU(Least Recently Used)算法是缓存技术中的一种常见思想,顾名思义,最近最少使用,也就是说有两个维度来衡量,一个是时间(最近),一个频率(最少).如果需要按优先级来对缓存中的K- ...

  9. 10行Java代码实现最近被使用(LRU)缓存

    在最近的面试中,我曾被多次问到,怎么实现一个最近最少使用(LRU)的缓存.缓存可以通过哈希表来实现,然而为这个缓存增加大小限制会变成另一个有意思的问题.现在我们看一下怎么实现. 最近最少使用缓存的回收 ...

随机推荐

  1. JAVA的三个版本,JSE,JEE,JME三者之间的区别

    JAVA是一种面向对象语言由SUN公司出品 J针对不同的使用方向规划出JSE,JEE,JME三个版本 1.JSE 指标准版一般用于用户学习JAVA语言的基础也是使用其他两个版本的基础主要用于编写C/S ...

  2. 在MVC中Dashboard基础入门操作

    DevExpress中的Dashboard这个图形插件真的很好用, 只需要在设计器绑定数据就行了,完全不用写后台代码.我也是刚学这个插件,可能还有一些我没有了解的知识点,忘各位大佬不吝赐教.我写这篇博 ...

  3. git 版本回滚

    1.克隆代码到本地 git clone http://qtools@dev.qtoolsbaby.cn:81/gitlab/qtools/jenkins_ceshi.git 2.git log 查看所 ...

  4. [C++项目]2048控制台游戏

    #include <iostream> #include <windows.h> #include <ctime> using namespace std; ; ; ...

  5. Oracle timestamp类型转换成date类型

    今天需要根据时间判断,统一修改某一个字段的数据.然后打开数据库发现,时间类型为timestamp类型.如下: 然后呢,这对我不是喝口水就可以解决的问题吗? 解决方案如下:我需要改这张表某个字段的内容, ...

  6. antd form 自定义验证表单使用方法

    import React from 'react'; import classNames from 'classnames'; export default class FormClass exten ...

  7. spring整合redis使用RedisTemplate的坑Could not get a resource from the pool

    一.背景 项目中使用spring框架整合redis,使用框架封装的RedisTemplate来实现数据的增删改查,项目上线后,我发现运行一段时间后,会出现异常Could not get a resou ...

  8. 【linux】Python3.6安装报错 configure: error: no acceptable C compiler found in $PATH

    安装python的时候出现如下的错误: [root@master ~]#./configure --prefix=/usr/local/python3.6 checking build system ...

  9. 清北学堂4.28Day1(重大更新详见贪心例一)

    枚举 用题目中给定的检验条件判定哪些是无用的,哪些是有用 的.能使命题成立的即为其解 . 例一 一棵苹果树上有n个苹果,每个苹果长在高度为Ai的地方.小明的身高为x 他想知道他最多能摘到多少苹果 数据 ...

  10. python第十三天,函数的嵌套定义,global,nonlocal关键字的使用,闭包及闭包的运算场景,装饰器

    今日内容 1. 函数的嵌套定义 2.global,nonlocal关键字 3.闭包及闭包的运用场景 4.装饰器 函数的嵌套定义 1. 概念:在一个函数内部定义另一个函数 2 .为什么要有函数的嵌套定义 ...