LinkedHashMap 继承了 HashMap
所以LinkedHashMap也是一种k-v的键值对,并且内部是双链表的形式维护了插入的顺序
LinkedHashMap如何保证顺序插入的?
在HashMap中时候说到过HashMap插入无序的
LinkedHashMap使用了双向链表,内部的node节点包含了分别指向前驱和后驱的before和after两个指针
LinkedHashMap的特点有哪些?
- 可以维持插入顺序
- 保证访问顺序,通过构造函数可以设置LinkedHashMap的访问顺序,采用了LRU算法(保证最近访问的元素都在链表的末尾
底层原理
插入元素
在使用debug去put元素的时候会发现调用了HashMap的put方法,由于LinkedHashMap继承了HashMap,内部会调用put方法,
但他们的实现逻辑不相同。不同点在于调用的newNode(int hash, K key, V value, Node<K,V> e)方法不同,LinkedHashMap会调用自己内部的newNode方法
LinkedHashMap添加了双向链表去维护节点和节点之间的前后映射关系,添加了Node节点。通过源码我们发现在创建新节点的时候同步的也会创建before和after两个分别指向前驱节点和后驱节点的指针,这样保证了节点和节点之间相互之间能够非常明确
查找元素
通过get方法访问指定key,在debug断点调试的过程中发现代码并没有执行第二个if判断里的逻辑,这是为什么呢?什么时候accessOrder会为true呢?accessOrder的作用是什么?
其实我们还通过构造函数可以设置LinkedHashMap的访问顺序,其内部采用了LRU算法(最近最久未使用),每次被get的元素会放在集合的末尾,保证最近访问的元素都在链表的末尾。那怎么开启这项功能呢?
如下图,在创建LinkedHashMap对象的时候可以定义设置初始容量、加载因子以及开启顺序访问,当对象初始化成功之后accessOrder就被置为true,
上述中afterNodeAccess方法的作用是什么呢?是在访问节点后,将节点移动到链表的尾部,此时在get元素之后我们在输出集合发现顺序改变了。
删除元素和修改元素和LinkedList原理相同,修改指针的指向并且置删除位置为null