一、 概述

在理解了HashMap后,我们来学习LinkedHashMap的工作原理及实现。首先还是类似的,我们写一个简单的LinkedHashMap的程序:

LinkedHashMap<String, Integer> lmap = new LinkedHashMap<String, Integer>();
lmap.put("语文", 1);
lmap.put("数学", 2);
lmap.put("英语", 3);
lmap.put("历史", 4);
lmap.put("政治", 5);
lmap.put("地理", 6);
lmap.put("生物", 7);
lmap.put("化学", 8);
for(Entry<String, Integer> entry : lmap.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());
}

运行结果是:

语文: 1
数学: 2
英语: 3
历史: 4
政治: 5
地理: 6
生物: 7
化学: 8

我们可以观察到,和HashMap的运行结果不同,LinkedHashMap的迭代输出的结果保持了插入顺序。是什么样的结构使得LinkedHashMap具有如此特性呢?我们还是一样的看看LinkedHashMap的内部结构,对它有一个感性的认识:

没错,正如官方文档所说:

Hash table and linked list implementation of the Map interface, with predictable iteration order. This implementation differs from HashMap in that it maintains a doubly-linked listrunning through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).

LinkedHashMap是Hash表和链表的实现,并且依靠着双向链表保证了迭代顺序是插入的顺序。

二、 三个重点实现的函数

在HashMap中提到了下面的定义:

// Callbacks to allow LinkedHashMap post-actions
void afterNodeAccess(Node<K,V> p) { }
void afterNodeInsertion(boolean evict) { }
void afterNodeRemoval(Node<K,V> p) { }

LinkedHashMap继承于HashMap,因此也重新实现了这3个函数,顾名思义这三个函数的作用分别是:节点访问后、节点插入后、节点移除后做一些事情。

afterNodeAccess函数

void afterNodeAccess(Node<K,V> e) { // move node to lastLinkedHashMap.Entry<K,V> last;// 如果定义了accessOrder,那么就保证最近访问节点放到最后if (accessOrder && (last = tail) != e) {LinkedHashMap.Entry<K,V> p =(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;p.after = null;if (b == null)head = a;elseb.after = a;if (a != null)a.before = b;elselast = b;if (last == null)head = p;else {p.before = last;last.after = p;}tail = p;++modCount;}
}

就是说在进行put之后就算是对节点的访问了,那么这个时候就会更新链表,把最近访问的放到最后,保证链表。

afterNodeInsertion函数

void afterNodeInsertion(boolean evict) { // possibly remove eldestLinkedHashMap.Entry<K,V> first;// 如果定义了溢出规则,则执行相应的溢出if (evict && (first = head) != null && removeEldestEntry(first)) {K key = first.key;removeNode(hash(key), key, null, false, true);}
}

如果用户定义了removeEldestEntry的规则,那么便可以执行相应的移除操作。

afterNodeRemoval函数

void afterNodeRemoval(Node<K,V> e) { // unlink// 从链表中移除节点LinkedHashMap.Entry<K,V> p =(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;p.before = p.after = null;if (b == null)head = a;elseb.after = a;if (a == null)tail = b;elsea.before = b;
}

这个函数是在移除节点后调用的,就是将节点从双向链表中删除。

我们从上面3个函数看出来,基本上都是为了保证双向链表中的节点次序或者双向链表容量所做的一些额外的事情,目的就是保持双向链表中节点的顺序要从eldest到youngest。

三、 put和get函数

put函数在LinkedHashMap中未重新实现,只是实现了afterNodeAccessafterNodeInsertion两个回调函数。get函数则重新实现并加入了afterNodeAccess来保证访问顺序,下面是get函数的具体实现:

public V get(Object key) {Node<K,V> e;if ((e = getNode(hash(key), key)) == null)return null;if (accessOrder)afterNodeAccess(e);return e.value;
}

值得注意的是,在accessOrder模式下,只要执行get或者put等操作的时候,就会产生structural modification。官方文档是这么描述的:

A structural modification is any operation that adds or deletes one or more mappings or, in the case of access-ordered linked hash maps, affects iteration order. In insertion-ordered linked hash maps, merely changing the value associated with a key that is already contained in the map is not a structural modification. In access-ordered linked hash maps, merely querying the map with get is a structural modification.

最后

按照国际惯例,给大家分享一套十分好用的Android进阶资料:《全网最全Android开发笔记》。

整个笔记一共8大模块、729个知识点,3382页,66万字,可以说覆盖了当下Android开发最前沿的技术点,和阿里、腾讯、字节等等大厂面试看重的技术。

因为所包含的内容足够多,所以,这份笔记不仅仅可以用来当学习资料,还可以当工具书用。

如果你需要了解某个知识点,不管是Shift+F 搜索,还是按目录进行检索,都能用最快的速度找到你要的内容。

相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照整个知识体系编排的。

详细文档可以点我下载,记得点赞哦~

(一)架构师必备Java基础

1、深入理解Java泛型

2、注解深入浅出

3、并发编程

4、数据传输与序列化

5、Java虚拟机原理

6、高效IO

……

(二)设计思想解读开源框架

1、热修复设计

2、插件化框架设计

3、组件化框架设计

4、图片加载框架

5、网络访问框架设计

6、RXJava响应式编程框架设计

……

(三)360°全方位性能优化

1、设计思想与代码质量优化

2、程序性能优化

  • 启动速度与执行效率优化
  • 布局检测与优化
  • 内存优化
  • 耗电优化
  • 网络传输与数据储存优化
  • APK大小优化

3、开发效率优化

  • 分布式版本控制系统Git
  • 自动化构建系统Gradle

……

(四)Android框架体系架构

1、高级UI晋升

2、Android内核组件

3、大型项目必备IPC

4、数据持久与序列化

5、Framework内核解析

……

(五)NDK模块开发

1、NDK开发之C/C++入门

2、JNI模块开发

3、Linux编程

4、底层图片处理

5、音视频开发

6、机器学习

……

(六)Flutter学习进阶

1、Flutter跨平台开发概述

2、Windows中Flutter开发环境搭建

3、编写你的第一个Flutter APP

4、Flutter Dart语言系统入门

……

(七)微信小程序开发

1、小程序概述及入门

2、小程序UI开发

3、API操作

4、购物商场项目实战

……

(八)kotlin从入门到精通

1、准备开始

2、基础

3、类和对象

4、函数和lambda表达式

5、其他

……

好啦,这份资料就给大家介绍到这了,*有需要详细文档的小伙伴可以点我下载~~~~*

I开发

3、API操作

4、购物商场项目实战

……

[外链图片转存中…(img-1J8gPf5S-1624348503461)]

(八)kotlin从入门到精通

1、准备开始

2、基础

3、类和对象

4、函数和lambda表达式

5、其他

……

[外链图片转存中…(img-g2G6o0W7-1624348503462)]

好啦,这份资料就给大家介绍到这了,*有需要详细文档的小伙伴可以点我下载~~~~*

@@程序员——看完源码记不住?掌握这套方法,Alibaba不会少你一个工位,年薪60w+小菜一碟!相关推荐

  1. 看完源码记不住,是我记性太差了吗?

    都说大厂面试必问源码,尤其是现在最流行的Java 开发技术--Spring的源码.可很多人看完Spring源码记不住,是记性太差了吗? 当然不是!是因为你没有掌握学习源码的技巧. 看完源码的我- 前段 ...

  2. 看完Spring源码记不住,是我脑子不太好吗?

    都说大厂面试必问源码,可很多人看完Spring源码记不住,是脑子有问题吗?当然不是!是因为你没有掌握学习源码的技巧. 看完源码的我- 我的朋友"路神"子路和"大魔王&qu ...

  3. java写一个简单的浪漫代码_2020浪漫七夕:7款程序员必备表白源码(超炫酷)

    2020七夕将要来临,php中文网给大家准备了七款程序员表白专用源码,让你可以一举俘获美人心,下面就来看一看这七款表白代码大全,包含html.html5.CSS.JQ编写的一些非常简单实用的表白代码, ...

  4. java写一个简单的浪漫代码,2018浪漫七夕:7款程序员必备表白源码(超炫酷)

    2018七夕将要来临,php中文网给大家准备了七款程序员表白专用源码,让你可以一举俘获美人心,下面就来看一看这七款表白代码大全,包含html.html5.CSS.JQ编写的一些非常简单实用的表白代码, ...

  5. 程序员表白简短html代码,【杂谈】2018浪漫七夕:7款程序员必备表白源码(超炫酷)...

    2018七夕将要来临,ki4网给大家准备了七款程序员表白专用源码,让你可以一举俘获美人心,下面就来看一看这七款表白代码大全,包含html.html5.CSS.JQ编写的一些非常简单实用的表白代码,非常 ...

  6. 程序员离职带走源码竟获利800万,网友:我一般都是删库跑路

    程序员辞职带走自己写的源码算违法吗? 程序员属于特殊职业,正常来说,公司会与程序员签订保密或所有权协议的.如果没有签订,按照法理来推论,在工作期间所有制作或参与的代码都属于公司财产,属于工作内容范围内 ...

  7. 程序员圣诞节相册源码_程序员分享圣诞刷屏源码,这次朋友圈千万不要再@微信官方了!...

    明天就到圣诞节了 每年到这个时候,朋友圈里都会掀起@微信官方要「圣诞皮肤」的骚操作,最常见的就是加个圣诞小帽了. 当然这种事情很多 P 图软件都可以做到,但在使用这些软件时,经常会被要求绑定微信等个人 ...

  8. server sql 多表事物 自增id_最实用的 SQL 语句收藏,程序员看完这篇就够了!

    分享阅读: 从自媒体写手,到程序员大神,我花了整整5年时间才拿下腾讯offer(Java方向)​zhuanlan.zhihu.com 一个月读完这本<程序员宝典>,我从网易严选跳槽到了阿里 ...

  9. 程序员老黄历Java源码实现

    今早起来,无聊之际把程序员老黄历用Java实现了一番. 原JS版地址:http://sandbox.runjs.cn/show/ydp3it7b/ 尊重原作--哈哈哈(连备注都复制的人是不是很恶心的? ...

最新文章

  1. 性能超越图神经网络,将标签传递和简单模型结合实现SOTA
  2. mxnet nd中的asscalar() 向量转换为标量 转
  3. SDUTOJ2779_找朋友(BFS | | DFS双解法)
  4. 一篇年薪60万的JVM性能调优文章
  5. js-jquery-插件开发(一)
  6. 3D渲染集群,听说过吗?
  7. itext 生成pdf 输出特殊符号_JAVA提取PDF内容及转换PDF为图片
  8. 解密小程序码:36条放射线
  9. 英伟达控制面板打不开的解决办法
  10. 服务器安装Ubuntu Server 18.04及磁盘分区
  11. 【打印机】mac上添加打印机
  12. adlink.php id=,利用BIOS-ID获得主板的信息
  13. 计算机道德 英语作文,关于道德英语作文
  14. 推荐系统的冷启动与效果评估
  15. 无人驾驶学习笔记-NDT 配准
  16. 大数据学习之路-Hive
  17. 叮叮获取所有用户信息_钉钉小程序获取用户信息
  18. Mac创建txt文件的两种方法
  19. Http Live Streaming介绍和应用
  20. 在C#中使用WIA获取扫描仪数据(三、利用Filter处理图片)

热门文章

  1. WOJ-204 继续找相同
  2. android闹铃备忘录代码,求推荐一个安卓手机上用的闹钟提醒的备忘录便签
  3. Devc++设置代码自动补全\提示
  4. nfl定理_NFL 2020预览与python冲
  5. vue+echarts 地图携带参数下钻【demo一】
  6. C# 驱动卸载 / UniSysDriver
  7. C语言:1027.自定义函数求最大公约数和最小公倍数
  8. 干货|货架对地面载荷的计算方法
  9. 【光学】基于matlab实现单缝衍射
  10. 计算机组成原理branch,处理器结构--分支预测(Branch Prediction)