newNode
// 在新增node的时候会调用这里,用额外的一个双向链表来记录内部key的顺序
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
LinkedHashMap.Entry<K,V> last = tail;
tail = p;
// 如果没有last,说明是空的,直接放入头部
if (last == null)
head = p;
else {
// 如果有放入尾部
p.before = last;
last.after = p;
}
}
afterNodeAccess
// 说白了,这里就是将该节点放到顺序链表尾部
void afterNodeAccess(Node<K,V> e) { // move node to last
LinkedHashMap.Entry<K,V> last;
// 如果启动访问顺序,且当然读取的kv不是顺序链表的末尾
if (accessOrder && (last = tail) != e) {
// 拿到该node的前后继节点
LinkedHashMap.Entry<K,V> p =
(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
// 先断开后继节点
p.after = null;
// 如果没有前继节点,说明链表为空,直接作为头部
if (b == null)
head = a;
else
// 否则将前继对接后继
b.after = a;
// 如果后继节点存在,后继对接前继
if (a != null)
a.before = b;
else
// 如果不存在,说明是尾部,直接将前继赋予last
last = b;
// 如果链表为空,将该节点直接对接头部
if (last == null)
head = p;
// 将该节点放到链表末尾
else {
p.before = last;
last.after = p;
}
// 赋给tail
tail = p;
++modCount;
}
}