前言:

在学习LRU算法的时候,看到LruCache源码实现是基于LinkedHashMap,今天学习一下LinkedHashMap的好处以及如何实现lru缓存机制的。

需求背景:

LRU这个算法就是把最近一次使用时间离现在时间最远的数据删除掉,而实现LruCache将会频繁的执行插入、删除等操作,我们就会想到使用LinkedList,但是我们又要基于Key-Value来保存数据,这个时候我们就会想起HashMap,但是HashMap不能像linkedList那样保留数据的插入顺序,如果要使用HashMap的话可以使用它的一个子类LinkedHashMap。

LinkedHashMap介绍:

LinkedHashMap是Map接口哈希表和链接列表实现,具有可预知的迭代顺序。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变, LinkedHashMap实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。根据链表中元素的顺序可以分为:按插入顺序的链表,和按访问顺序(调用get方法)的链表。默认是按插入顺序排序,如果指定按访问顺序排序,那么调用get方法后,会将这次访问的元素移至链表尾部,不断访问可以形成按访问顺序排序的链表。 可以重写removeEldestEntry方法返回true值指定插入元素时移除最老的元素。更多关于LinkedHashMap的知识介绍请查看这篇博客,博客地址:http://www.cnblogs.com/children/archive/2012/10/02/2710624.html

LinkedHashMap使用:

因为我们这里为了实现LRU算法,排序方式 设置为true 访问顺序排序

        int initialCapacity = 10;//初始化容量
float loadFactor = 0.75f;//加载因子,一般是 0.75f
boolean accessOrder = true;//排序方式 false 基于插入顺序 true 基于访问顺序
Map<String, Integer> map = new LinkedHashMap<>(initialCapacity, loadFactor, accessOrder);

具体看下效果:

   for (int i = 0; i < 10; i++) {
map.put(String.valueOf(i), i);
}
//访问前顺序
for (Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, Integer> next = it.next();
Log.e(TAG, "linkedMap--before-->" + next.getKey());
} //模拟访问
map.get("5"); //访问后数据
for (Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, Integer> next = it.next();
Log.e(TAG, "linkedMap--after-->" + next.getKey());
}
}

运行结果发现访问过的5未知发生了变化 说明是基于访问排序的。我们接下来再看下如何移除过期的。

       final int initialCapacity = 10;//初始化容量
float loadFactor = 0.75f;//加载因子,一般是 0.75f
boolean accessOrder = true;//排序方式 false 基于插入顺序 true 基于访问顺序
//Map<String, Integer> map = new LinkedHashMap<>(initialCapacity, loadFactor, accessOrder);
Map<String, Integer> map = new LinkedHashMap(initialCapacity, loadFactor, accessOrder) { @Override
protected boolean removeEldestEntry(Entry eldest) {
return size() > initialCapacity;
}
};
for (int i = 0; i < 15; i++) {
map.put(String.valueOf(i), i);
}
//访问前顺序
for (Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, Integer> next = it.next();
Log.e(TAG, "linkedMap--before-->" + next.getKey());
}

我们容量定的10个,我们插入15个 我们发现最先插入的五个不见了,说明LRU算法起到效果了。

Java学习之LinkedHashMap学习总结的更多相关文章

  1. Java LinkedHashMap学习

    以前一直使用HashMap,今天学习一下LinkedHashMap JavaDoc 注解: Hash table and linked list implementation of the Map i ...

  2. JDK源码学习笔记——LinkedHashMap

    HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序. LinkedHashMap保证了元素迭代的顺序.该迭代顺序可以是插入顺序或者是访问顺序.通过维护一个 ...

  3. 20145304 Java第八周学习报告

    20145304<Java程序设计>第八周学习总结 教材学习内容总结 NIO NIO使用频道来衔接数据节点,在处理数据时,NIO可以让你设定缓冲区容量,在缓冲区中对感兴趣的数据区块进行标记 ...

  4. 20145304 Java第七周学习报告

    20145304<Java程序设计>第七周学习总结 教材学习内容总结 1.时间的度量: 格林威治标准时间(GMT)通过观察太阳而得,其正午是太阳抵达天空最高点之时,因地球的公转与自传,会造 ...

  5. 20145304 Java第六周学习报告

    20145304<Java程序设计>第六周学习总结 教材学习内容总结 1.InputStream与OutputStream: 在Java中,输入串流的代表对象为java.io.InputS ...

  6. 20145304 Java第三周学习报告

    20145304 <Java程序设计>第三周学习总结 教材学习内容总结 1.定义类: 类定义时使用class关键词,建立实例要使用new关键词. 代码如下: /*定义类 书上例子 衣服的型 ...

  7. 20145304 刘钦令 Java程序设计第二周学习总结

    20145304 <Java程序设计>第2周学习总结 教材学习内容总结 java可区分基本类型和类类型(即参考类型)两大类型系统. 基本类型主要可区分为整数.字节.浮点数.字符与布尔. 整 ...

  8. 20145304 刘钦令 Java程序设计第一周学习总结

    20145304<Java程序设计>第1周学习总结 教材学习内容总结 1995年5月23日,是公认的Java的诞生日,Java正式由Oak改名为Java. Java的三大平台是:Java ...

  9. java JDK8 学习笔记——助教学习博客汇总

    java JDK8 学习笔记——助教学习博客汇总 1-6章 (by肖昱) Java学习笔记第一章——Java平台概论 Java学习笔记第二章——从JDK到IDEJava学习笔记第三章——基础语法Jav ...

随机推荐

  1. hadoop 2.7.3本地环境运行官方wordcount-基于HDFS

    接上篇<hadoop 2.7.3本地环境运行官方wordcount>.继续在本地模式下测试,本次使用hdfs. 2 本地模式使用fs计数wodcount 上面是直接使用的是linux的文件 ...

  2. 【翻译】MongoDB指南/CRUD操作(一)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(一) 主要内容:CRUD操作简介,插入文档,查询文档. CRUD操作包括创建.读取.更新和删 ...

  3. Convert BSpline Curve to Arc Spline in OpenCASCADE

    Convert BSpline Curve to Arc Spline in OpenCASCADE eryar@163.com Abstract. The paper based on OpenCA ...

  4. [版本控制之道] Git 常用的命令总结(欢迎收藏备用)

    坚持每天学习,坚持每天复习,技术永远学不完,自己永远要前进 总结日常开发生产中常用的Git版本控制命令 ------------------------------main-------------- ...

  5. WebApi - 路由

    这段时间的博客打算和大家一起分享下webapi的使用和心得,主要原因是群里面有朋友说希望能有这方面的文章分享,随便自己也再回顾下:后面将会和大家分不同篇章来分享交流心得,希望各位多多扫码支持和点赞,谢 ...

  6. 程序猿都没对象,JS竟然有对象?

    现在做项目基本是套用框架,不论是网上的前端还是后端框架,也会寻找一些封装好的插件拿来即用,但还是希望拿来时最好自己过后再回过头了解里面的原理,学习里面优秀的东西,不论代码封装性,还是小到命名. 好吧, ...

  7. 多线程 异步 beginInvoke EndInvoke 使用

    有许多耗时操作时,还要响应用户操作.这时候就需要用其他线程或者异步来搞.本来是改造公司的日志组件.因为多上了个国外大区的业务到来本系统来.这个系统其他地方都好就是日志,动不动就要死给我们看.有时候寻找 ...

  8. Nexus(一)环境搭建

    昨天,成功搭建了自己的 Maven 环境(详见:Maven(一)环境搭建),今天就来研究和探讨下 Nexus 的搭建! 使用背景: 安装环境:Windows 10 -64位 JDK版本:1.7 Mav ...

  9. 【干货分享】流程DEMO-借款申请

    流程名: 借款申请   业务描述: 当员工个人在工作中需要进行借款时,通过此项流程提交借款申请,审批通过后,财务部进行款项支付.   流程相关文件: 流程包.xml WebService业务服务.xm ...

  10. .net core和angular2之前端篇—1

    2016-10-20更新 今天的这篇文章还是一篇"Hello World",只不过开发环境有所改变--Visual Studio Code+Angular2+Webapck,也算是 ...