LinkedHashMap
继承自HashMap的,多线程不安全的、用于存储K、V键值对的,有序集合类。
在HashMap基础上,对存储的元素节点添加了前后指针、额外维护了一个双向链表维持顺序。由于增加了前后指针,当进行Put、Get、Replace等操作时,会有维护双向链表的额外开销。
使用迭代器遍历时比HM要快。使用场景是:当设定为按访问顺序存储时,适合做LRU缓存。
特点
-
LinkedHM的存储单元类型
使用Entry类作为存储类,继承自HashMap的Node类.
Entry类添加了before和after两个前后指针。 -
LinkedHM的采用的数据结构
在HashMap的基础上,对每个节点增加了before和after指针。
综合HashMap,LinkedHM使用的数据结构有数组、单向链表、双向链表、红黑树。 -
LinkedHM的Head和Tail的含义
LinkedHashMap对象内部含有head和tail两个指针。
如果用于实现LRU缓存,在语义上,Head表示最老,Tail表示最新。 -
LinkedHM的初始容量大小、负载因子
默认下大小、负载因子和HM一样。
也可通过构造函数指定。 -
LinkedHM插入顺序和访问顺序
1.插入顺序:默认情况accessOrder为False,使用的是插入序。表示元素在集合中遍历的顺序按插入时的顺序排列,PUT、GET、Replace等方法不会改变集合内元素的排列顺序。
2.访问顺序:需要在构造函数中将accessOrder设为true,每当访问元素,如调用get、replace、使用put操作更新值时,都会将操作的元素放到链表最后。适合实现LRU算法。 -
LinkedHM Get过程
1.通过调用父类HashMap的Get方法完成取元素。
2.如果设定了访问顺,则调用afterNodeAccess将访问的元素移到链表最后。 -
LinkedHM Put过程
1.调用父类HashMap的Put方法完成元素插入。
2.如果插入的元素已经存在,则视为更新操作,会调用afterNodeAccess将更新的元素放到链表最后一个位置。 -
LinkedHM和HashMap使用迭代器遍历时的区别
LinkedHM从链表头指针开始,依次遍历所有元素。
HM从0号数组开始按数组下标遍历, 如果数组为空,则继续向后找,直到找到不为空的数组元素,如果元素为一个链表或红黑树的根节点,则通过根节点向下遍历链表或红黑树。
LinkedHM迭代效率要高于HM,因为HM可能遍历到空元素。
LinkedHM对集合视图使用迭代器进行操作时不会改变集合内元素的顺序。 -
关于removeEldestEntry 方法
该方法默认返回为False。
当基于LinkedHM实现LRU缓存时,需要重写该方法,实现最久不用的元素的淘汰策略。
源码部分方法备注
1.LinkNodeLast方法
含义:尾部加一个节点P。
2.transferLinks方法
含义:使用Dst节点替换Src。
3.afterNodeAccess方法
含义:将访问到的节点e移动到最后一个,修复移动过程中破坏的前后指针。
4. afterNodeRemoval方法
含义:将节点e移除双向链表,然后修复指针。