0
点赞
收藏
分享

微信扫一扫

再探Java集合系列—LinkedHashMap


LinkedHashMap 继承了 HashMap

再探Java集合系列—LinkedHashMap_构造函数

所以LinkedHashMap也是一种k-v的键值对,并且内部是双链表的形式维护了插入的顺序

LinkedHashMap如何保证顺序插入的?

在HashMap中时候说到过HashMap插入无序的

再探Java集合系列—LinkedHashMap_链表_02

LinkedHashMap使用了双向链表,内部的node节点包含了分别指向前驱和后驱的before和after两个指针

再探Java集合系列—LinkedHashMap_构造函数_03

再探Java集合系列—LinkedHashMap_开发语言_04

LinkedHashMap的特点有哪些?

  • 可以维持插入顺序
  • 保证访问顺序,通过构造函数可以设置LinkedHashMap的访问顺序,采用了LRU算法(保证最近访问的元素都在链表的末尾

底层原理

插入元素

在使用debug去put元素的时候会发现调用了HashMap的put方法,由于LinkedHashMap继承了HashMap,内部会调用put方法,

再探Java集合系列—LinkedHashMap_构造函数_05

但他们的实现逻辑不相同。不同点在于调用的newNode(int hash, K key, V value, Node<K,V> e)方法不同,LinkedHashMap会调用自己内部的newNode方法

再探Java集合系列—LinkedHashMap_java_06

LinkedHashMap添加了双向链表去维护节点和节点之间的前后映射关系,添加了Node节点。通过源码我们发现在创建新节点的时候同步的也会创建before和after两个分别指向前驱节点和后驱节点的指针,这样保证了节点和节点之间相互之间能够非常明确

查找元素

通过get方法访问指定key,在debug断点调试的过程中发现代码并没有执行第二个if判断里的逻辑,这是为什么呢?什么时候accessOrder会为true呢?accessOrder的作用是什么?

再探Java集合系列—LinkedHashMap_构造函数_07

其实我们还通过构造函数可以设置LinkedHashMap的访问顺序,其内部采用了LRU算法(最近最久未使用),每次被get的元素会放在集合的末尾,保证最近访问的元素都在链表的末尾。那怎么开启这项功能呢?

如下图,在创建LinkedHashMap对象的时候可以定义设置初始容量、加载因子以及开启顺序访问,当对象初始化成功之后accessOrder就被置为true,

再探Java集合系列—LinkedHashMap_链表_08

上述中afterNodeAccess方法的作用是什么呢?是在访问节点后,将节点移动到链表的尾部,此时在get元素之后我们在输出集合发现顺序改变了。

再探Java集合系列—LinkedHashMap_java_09

删除元素和修改元素和LinkedList原理相同,修改指针的指向并且置删除位置为null

如果有想要交流的内容欢迎在评论区进行留言,如果这篇文档受到了您的喜欢那就留下你点赞+收藏+评论脚印支持一下博主~
举报

相关推荐

0 条评论