publicclassLinkedHashMap<K,V>extendsHashMap<K,V>implementsMap<K,V>{.../**
* 节点移除后的回调
*
* @param e 待移除的节点
*/voidafterNodeRemoval(Node<K, V> e){
LinkedHashMap.Entry<K, V> p =(LinkedHashMap.Entry<K, V>) e, b = p.before, a = p.after;// 待删除节点 p 的前置后置节点都置空
p.before = p.after = null;// 如果前置节点是 null,则现在的头结点应该是后置节点 aif(b == null)
head = a;else// 否则将前置节点 b 的后置节点指向 a
b.after = a;// 同理如果后置节点时 null,则尾节点应是 bif(a == null)
tail = b;else// 否则更新后置节点 a 的前置节点为 b
a.before = b;}...}
3.7、查操作
publicclassLinkedHashMap<K,V>extendsHashMap<K,V>implementsMap<K,V>{.../**
* 根据 key 查操作
*
* @param key 键
* @return 返回查找后的元素值,如果不存在则返回 null
*/public V get(Object key){
Node<K, V> e;if((e =getNode(hash(key), key))== null)return null;// 如果 accessOrder==true,则按照 LRU 算法排序if(accessOrder)afterNodeAccess(e);return e.value;}/**
* 根据 key 查操作
*
* @param key 键
* @param defaultValue 默认值
* @return 返回查找后的元素值,如果不存在则返回默认值
*/public V getOrDefault(Object key, V defaultValue){
Node<K, V> e;if((e =getNode(hash(key), key))== null)return defaultValue;// 如果 accessOrder==true,则按照 LRU 算法排序if(accessOrder)afterNodeAccess(e);return e.value;}/**
* 节点访问后的回调
* 主要作用:将当前被访问到的节点e,移动至内部的双向链表的尾部
*
* @param e 待访问的节点
*/voidafterNodeAccess(Node<K, V> e){
LinkedHashMap.Entry<K, V> last;// 原尾节点// 如果 accessOrder 是 true,且原尾节点不等于 eif(accessOrder &&(last = tail)!= e){// 节点 e 强转成双向链表节点 p
LinkedHashMap.Entry<K, V> p =(LinkedHashMap.Entry<K, V>) e, b = p.before, a = p.after;// p 现在是尾节点, 后置节点一定是 null
p.after = null;// 如果 p 的前置节点是 null,则 p 以前是头结点,所以更新现在的头结点是 p 的后置节点 aif(b == null)
head = a;else// 否则更新 p 的前直接点 b 的后置节点为 a
b.after = a;// 如果 p 的后置节点不是 null,则更新后置节点 a 的前置节点为 bif(a != null)
a.before = b;else// 如果原本 p 的后置节点是 null,则 p 就是尾节点。此时更新 last 的引用为 p 的前置节点 b
last = b;if(last == null)// 原本尾节点是 null 则,链表中就一个节点
head = p;else{// 否则更新当前节点 p 的前置节点为原尾节点 last,last 的后置节点是 p
p.before = last;
last.after = p;}// 尾节点的引用赋值成 p
tail = p;// 修改 modCount。++modCount;}}...}
4、重写 containsValue() 方法
publicclassLinkedHashMap<K,V>extendsHashMap<K,V>implementsMap<K,V>{.../**
* 判断是否存在 value 元素值
*
* @param value 查找的元素值
* @return 返回 true 代表存在,返回 false 代表不存在
*/publicbooleancontainsValue(Object value){// 遍历一遍链表,去比较有没有 value 相等的节点,并返回for(LinkedHashMapEntry<K, V> e = head; e != null; e = e.after){
V v = e.value;if(v == value ||(value != null && value.equals(v)))returntrue;}returnfalse;}...}
想对比 HashMap(两个for循环遍历)更加高效,之所以高效是因为新增的 after 链表可以将所有的元素串联起来。