LRUCache可以用于在内存中保持当前的热点数据,下面实现一个有大小限制的lru cache,相关如下:

1. 模板化;

2. 利用std::unordered_map实现o(1)查找,利用std::list实现o(1)删除 (双链表+hash表);

3. 用map保持key和结点在链表中的位置(iterator)

4. 需要同时考虑如下情况:

put操作:

(1) 如果当前key存在,则将对于的结点剪切到链表的头部,同时更新哈希表中value的值;

(2) 如果当前key不存在于hash表中,且元素个数已经达到最大值,则删除链表的最后一个结点,同时把新结点插入到链表的头部,同时更新hash表(增加新节点和删除旧结点表项);

get操作:

(1)检查当前hash表中是否有该key,如果存在,则将该key对应的结点move到list的头部,并同步更新map的value;

(2)如果hash表中不存在改key,则返回-1;

对应的代码如下:

#include <iostream>
#include <unordered_map>
#include <list>
#include <string>
#include <utility>template<class KeyType, class ValueType>
class LRUCache {
public:LRUCache(int capacity) : m_capacity(capacity) {}  int get(KeyType key, ValueType& value);//0-找到, -1-没找到int put(KeyType key, ValueType value);// 0-插入成功, -1 -插入失败void show() const; //展示当前LRUcache中的内容
private:typedef std::pair<KeyType, ValueType> Node;typedef typename std::list<Node>::iterator Iter;std::list<Node> m_list;//双向链表std::unordered_map<KeyType, Iter> m_map;//哈希表int m_capacity;//cache的最大元素个数
}; template<class KeyType, class ValueType>
int LRUCache<KeyType, ValueType>::get(KeyType key, ValueType& value) {if (m_map.count(key) <= 0) {return -1; }   //获取值Iter iter = m_map[key];//将值移到headm_list.splice(m_list.begin(), m_list, iter);return 0;
}template<class KeyType, class ValueType>
int LRUCache<KeyType, ValueType>::put(KeyType key, ValueType value) {//检查当前map中是否有该key,如果存在,则将该key对应的结点move到list的头部,并同步更新map的valueif (m_map.count(key) > 0) {Iter iter = m_map[key];iter->second = value; //充值map中key对应的valuem_list.splice(m_list.begin(), m_list, iter); //将对应的结点move到header} else {//检查当前元素是否达到容器的最大值,如果达到了阈值,则先将最后一个元素删除,将新元素插入到首部,同时更新mapNode node(key, value);if (m_list.size() == m_capacity) {m_map.erase(m_list.back().first);//将元素从map中删除m_list.pop_back();//移除最后一个元素}   //将新元素插入到map和list中m_list.push_front(node);m_map[key] = m_list.begin();}   return 0;
}template<class KeyType, class ValueType>
void LRUCache<KeyType, ValueType>::show() const {auto iter = m_list.begin(); auto iter_end = m_list.end();while (iter != iter_end) {std::cout << "(" << iter->first << "," << iter->second << ") ";iter++;}std::cout << std::endl;
}int main(int argc, char* argv[]) {LRUCache<std::string, int> cache(5);//先插入4个元素std::cout << "insert (aaa,111) (bbb,222) (ccc,333) (ddd,444) (eee,555)" << std::endl;cache.put("aaa", 111);cache.put("bbb", 222);cache.put("ccc", 333);cache.put("ddd", 444);cache.put("eee", 555);cache.show();//访问元素cccint result = 0;cache.get("ccc", result);std::cout << "after visit ccc" << std::endl;cache.show();//再插入一个元素("fff",666)cache.put("fff", 666);std::cout << "insert (fff,666)" << std::endl;cache.show();return 0;
}

输出结果如下:

insert (aaa,111) (bbb,222) (ccc,333) (ddd,444) (eee,555)
(eee,555) (ddd,444) (ccc,333) (bbb,222) (aaa,111) 
after visit ccc
(ccc,333) (eee,555) (ddd,444) (bbb,222) (aaa,111) 
insert (fff,666)
(fff,666) (ccc,333) (eee,555) (ddd,444) (bbb,222)

LRUCache的C++实现相关推荐

  1. 内存缓存LruCache的简单使用

    LruCache算法(Least Recently Used),也叫近期最少使用算法. 这个类非常适合用来缓存图片,它的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中,并 ...

  2. Android 图片缓存之内存缓存技术LruCache,软引用

    Android 图片缓存之内存缓存技术LruCache,软引用

  3. 关于 npm 中 lru-cache 之 maxAge 盲点 源码分析

    下面copy了一段实例 var LRU = require("lru-cache") , options = { max: 500 , length: function (n, k ...

  4. Android LruCache 压缩图片 有效避免程序OOM

    压缩加载大图片 我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状.不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小.比如说系统图片库里展示的图片大都是 ...

  5. LruCache缓存处理及异步加载图片类的封装

    Android中的缓存处理及异步加载图片类的封装   一.缓存介绍: (一).Android中缓存的必要性: 智能手机的缓存管理应用非常的普遍和需要,是提高用户体验的有效手段之一. 1.没有缓存的弊端 ...

  6. 图片缓存之内存缓存技术LruCache,软引用

    图片缓存之内存缓存技术LruCache,软引用 每当碰到一些大图片的时候,我们如果不对图片进行处理就会报OOM异常, 这个 问题曾经让我觉得很烦恼 ,后来终于得到了解决, 那么现在就让我和大家一起分享 ...

  7. LruCache 源码解析

    前言: 没看懂LruCache之前,我擦, LruCache这个类设计有啥意义? LinkedHashMap 完全可以代替.看懂之后,设计的真好. LruCache 概念描述 一般来说,缓存策略主要包 ...

  8. LruCache原理

    创建LruCache对象,重写其中的sizeOf方法: 然后看看LruCache内部长啥样子??? 看到A处,这里有个LinkedHashMap,这个是专门来存要缓存的对象,这个数据结构有个特点即链表 ...

  9. [置顶] 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅

    转载请注明出处http://blog.csdn.net/xiaanming/article/details/9825113 异步加载图片的例子,网上也比较多,大部分用了HashMap<Strin ...

  10. LruCache缓存机制

    LruCache: Android提供的使用了(Least Recently Used)近期最少使用算法的缓存类 内部基于LinkedHashMap实现 实现这个主要需要重写 构造时需要确定Cache ...

最新文章

  1. 2022-2028年中国车载天线行业市场前瞻与投资战略规划分析报告
  2. 2023 USNews全美计算机研究生院排名发布!MIT、CMU分别称霸总榜和AI分榜
  3. 10多所高校发布通知: 今年研究生复试或有变!
  4. 【Python】5个方便好用的Python自动化脚本
  5. Python多线程(自学必备 超详细)
  6. 8999元起!vivo X Fold折叠屏旗舰今日首销:采用航天级浮翼式铰链
  7. Linux 硬中断和软中断
  8. Spring Cloud 中的@FeignClient注解
  9. Python:暴力破解密码
  10. 延迟队列DelayQueue原理
  11. 从SHAttered事件谈安全
  12. Web爬虫|入门教程之爬虫简介
  13. 二分法(Bisection)求解单根(python,数值积分)
  14. 个人财务管理系统beancount-gs
  15. 安卓+ios系统--手机端页面自适应手机屏幕大小,禁止手动放大和缩小VUE
  16. python绘制拟合回归散点图_matplotlib中散点图的回归线和拟合曲线
  17. Blender 利用遮罩剔除顶点
  18. 生成Android平台签名证书(.keystore)
  19. Matlab怎么计算信号的能量,学习用Matlab计算离散信号的功率和能量.PPT
  20. html 指定 favicon,favicon 不只是个图标

热门文章

  1. ExecutorUtil
  2. Learning to Rank(以下简称L2R)
  3. LightWave 3D 2019 for Mac(三维动画制作软件)
  4. 各行各业数据及分析研究报告网站参考
  5. android 陀螺仪源码,陀螺仪源码 android
  6. 共振峰估计2MATLAB
  7. 《算法第一步》出版啦!
  8. sublime text 打开总是弹框报错Unable to download XXX. Please view the console for more details.解决办法
  9. c语言利用rand()函数生成一组不重复的随机数
  10. Gmail附件大小及格式限制全面解析