static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;//增加了先后指针来形成双向链表
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}

/**
*/

/**
* The tail (youngest) of the doubly linked list.尾部
*/

//true访问顺序 false插入顺序
final boolean accessOrder;

    private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
tail = p;
if (last == null)
else {
p.before = last;
last.after = p;
}
}

    private void transferLinks(LinkedHashMap.Entry<K,V> src,
LinkedHashMap.Entry<K,V> b = dst.before = src.before;
LinkedHashMap.Entry<K,V> a = dst.after = src.after;
if (b == null)
else
b.after = dst;
if (a == null)
tail = dst;
else
a.before = dst;
}

    void reinitialize() {
super.reinitialize();
}

    Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
return p;
}

    Node<K,V> replacementNode(Node<K,V> p, Node<K,V> next) {
return t;
}

    TreeNode<K,V> newTreeNode(int hash, K key, V value, Node<K,V> next) {
TreeNode<K,V> p = new TreeNode<K,V>(hash, key, value, next);//生成一个TreeNode，next指向参数next
return p;
}

replacementTreeNode根据结点p生成一个新的TreeNode，next设为给定的next，替换原本的p
    TreeNode<K,V> replacementTreeNode(Node<K,V> p, Node<K,V> next) {
TreeNode<K,V> t = new TreeNode<K,V>(q.hash, q.key, q.value, next);
return t;
}

    void afterNodeRemoval(Node<K,V> e) {
(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
p.before = p.after = null;
if (b == null)
else
b.after = a;
if (a == null)
tail = b;
else
a.before = b;
}

afterNodeInsertion可能移除最旧的结点，需要evict为true同时链表不为空同时removeEldestEntry需要重写
    void afterNodeInsertion(boolean evict) {
if (evict && (first = head) != null && removeEldestEntry(first)) {//removeEldestEntry需要重写才从发挥作用，否则一定返回false
K key = first.key;//移除链表头部的结点
removeNode(hash(key), key, null, false, true);
}
}

afterNodeAccess在访问过后将结点e移动到链表尾部，需要Map是access-order，若移动成功则增加modCount
    void afterNodeAccess(Node<K,V> e) {
if (accessOrder && (last = tail) != e) {//Map是access-order同时e不是链表的尾部
(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
p.after = null;
if (b == null)//将结点e从链表中剪下
else
b.after = a;
if (a != null)
a.before = b;
else
last = b;
if (last == null)
else {
p.before = last;
last.after = p;
}
tail = p;//结点e移动到链表尾部
++modCount;//因为有access-order下结点被移动，所以增加modCount
}
}

containsValue遍历链表寻找相等的value值，这个操作一定不会造成结构改变

    public boolean containsValue(Object value) {
V v = e.value;
if (v == value || (value != null && value.equals(v)))
return true;
}
return false;
}

get方法复用HashMap的getNode方法，若找到结点且Map是访问顺序时，要将访问的结点放到链表最后，若没找到则返回null。而getOrDefault仅有的区别是没找到时返回defaultValue

    public V get(Object key) {
Node<K,V> e;
if ((e = getNode(hash(key), key)) == null)//复用HashMap的getNode方法
return null;
if (accessOrder)
afterNodeAccess(e);//access-order时将e放到队尾
return e.value;
}

public V getOrDefault(Object key, V defaultValue) {
Node<K,V> e;
if ((e = getNode(hash(key), key)) == null)
return defaultValue;//复用HashMap的getNode方法，若没有找到对应的结点则返回defaultValue
if (accessOrder)
afterNodeAccess(e);//access-order时将e放到队尾
return e.value;
}

    public void clear() {
super.clear();
}

removeEldestEntry在put和putAll插入键值对时调用，原本是一定返回false的，如果要自动删除最旧的键值对要返回true，需要进行重写。比如下面这个例子，控制size不能超过100
     private static final int MAX_ENTRIES = 100;

protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_ENTRIES;
}

    public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
keySet = ks;
}
return ks;//返回key值的set
}

public Collection<V> values() {
Collection<V> vs = values;
if (vs == null) {
values = vs;
}
return vs;//返回一个包含所有value值的Collection
}

public Set<Map.Entry<K,V>> entrySet() {
Set<Map.Entry<K,V>> es;
return (es = entrySet) == null ? (entrySet = new LinkedEntrySet()) : es;//返回一个含有所有键值对的Set
}

            if (e != null) { // 找到了相同的key则修改value值并返回旧的value
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}

+ 订阅