JDK1.8LinkedHashMap实现原理及源码分析
首先附上我的几篇其它文章链接感兴趣的可以看看,如果文章有异议的地方欢迎指出,共同进步,顺便点赞谢谢!!!
Android framework 源码分析之Activity启动流程(android 8.0)
Android studio编写第一个NDK工程的过程详解(附Demo下载地址)
面试必备1:HashMap(JDK1.8)原理以及源码分析
Android事件分发机制原理及源码分析
View事件的滑动冲突以及解决方案
Handler机制一篇文章深入分析Handler、Message、MessageQueue、Looper流程和源码
Android三级缓存原理及用LruCache、DiskLruCache实现一个三级缓存的ImageLoader
概述
本文对LinkedHashMap的源码分析是基于JDK1.8,因为LinkedHashMap是在HashMap的基础上进行的功能扩展,所以需要掌握HashMap的源码和实现原理,如果不了解请先阅读我的另一篇HashMap的实现原理和源码分析
重点:本文如果有分析的不对的地方请大家留言指正!!!!!
再次强调一下:读此文章之前需要先去了解HashMap的源码请先阅读我的另一篇HashMap的实现原理和源码分析,以便理解。
LinkedHashMap的数据结构
想要知道 LinkedHashMap的实现原理,就必须先去了解它的数据结构(即存储机制),和HashMap一样LinkedHashMap的数据结构也是通过数组和链表组成的散列表,同样线程也是不安全的允许null值null键
,不同的是LinkedHashMap在散列表的基础上内部维持的是一个双向链表在每次增、删、改、 查时增加或删除或调整链表的节点顺序。
- 在默认情况下LinkedHashMap遍历时的顺序是按照插入节点顺序,我们可一再构造器中通过传入
accessOrder=true
参数,使得其遍历顺序按照访问的顺序输出。 - 因继承自HashMap的一些特性LinkedHashMap都有,比如扩容的策略,哈希桶长度一定是2的N次方等等。
- 本质上LinkedHashMap是通过复写父类HashMap的几个抽象方法,去实现有序输出
LinkedHashMap的链表节点LinkedHashMapEntry<K,V>:
LinkedHashMap与HashMap都是有数组和链表组成的散列表,不同的是LinkedHashMap的LinkedHashMapEntry<K,V>
继承HashMap的Node<K,V>
,并在其基础上进行扩展成一个双向链表其源码如下:
static class LinkedHashMapEntry<K,V> extends HashMap.Node<K,V> {
LinkedHashMapEntry<K,V> before, after;//分别指向当前节点的前后节点
LinkedHashMapEntry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);//其他的就是父类HashMap的Node
}
}
此外LinkedHashMap还增加了两个成员变量分别指向链表的头节点和尾节点
/**
* The head (eldest) of the doubly linked list.
*/
transient LinkedHashMapEntry<K,V> head;
/**
* The tail (youngest) of the doubly linked list.
*/
transient LinkedHashMapEntry<K,V> tail;
增、改put(key,value)方法源码
LinkedHashMap并没有重写HashMap的put、putVal()方法,只是重写了putVal()中调用的以下三个方法
- 构建新节点时调用的
newNode()
方法,去构建LinkedHashMapEntry节点,而不是Node节点 - 节点被访问后
afterNodeAccess(e)
抽象方法 - 节点被插入后
afterNodeInsertion(evict)
抽象方法
p