LinkedHashMap源码分析
1. LinkedHashMap.Entry
LinkedHashMap继承自HashMap,在其内部维护了一个双向链表
static class Entry<K,V> extends HashMap.Node<K,V> { // HashMap.TreeNode继承自此类 Entry<K,V> before, after; // 前置节点和后置节点 Entry(int hash, K key, V value, Node<K,V> next) { super(hash, key, value, next); } }
2. LinkedHashMap
1' get + afterNodeAccess + accessOrder(true):将被访问的节点移至双向链表尾部
2' newNode、newTreeNode:将新插入节点添加到双向链表尾部
3' afterNodeInsertion + removeEldestEntry:新插入节点后,删双向链表头节点(最旧节点)
4' afterNodeRemoval:维护节点前后指针、双向链表头尾节点
5' replacementNode:红黑树转链表时,维护节点前后指针、双向链表头尾节点
6' replacementTreeNode:链表转红黑树时,维护节点前后指针、双向链表头尾节点
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> { ...transient LinkedHashMap.Entry<K,V> head; // 双向链表头节点 transient LinkedHashMap.Entry<K,V> tail; // 双向链表尾节点 // accessOrder置为true && 继承LinkedHashMap,覆盖removeEldestEntry方法:可实现LRU(Least Recently Used)算法 final boolean accessOrder;
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { return false; } ... public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor); this.accessOrder = accessOrder; } // 覆盖(accessOrder + afterNodeAccess) public V get(Object key) { Node<K,V> e; if ((e = getNode(hash(key), key)) == null) // HashMap.getNode return null; if (accessOrder) afterNodeAccess(e); // 在访问e后,将e移至双向链表尾部 return e.value; } // 覆盖(HashMap中为noop),见HashMap.putVal方法 void afterNodeAccess(Node<K,V> e) { LinkedHashMap.Entry<K,V> last; if (accessOrder && (last = tail) != e) { // accessOrder && e不是双向链表尾节点 LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after; p.after = null; if (b == null) // p为头结点 head = a; else b.after = a; if (a != null) // p非尾节点 a.before = b; else last = b; if (last == null) // a == b == null head = p; else { p.before = last; last.after = p; } tail = p; ++modCount; } } // 覆盖(HashMap中为noop),见HashMap.putVal方法 void afterNodeInsertion(boolean evict) { // 删除双向链表头节点 LinkedHashMap.Entry<K,V> first; // evit(为true,见HashMap.put方法)&& 双向链表不为空 && removeEldestEntry条件成立 if (evict && (first = head) != null && removeEldestEntry(first)) { K key = first.key; removeNode(hash(key), key, null, false, true); } } // 覆盖(HashMap.Node -> LinkedHashMap.Entry + 将节点添加到双向链表尾部),见HashMap.putVal方法 Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) { LinkedHashMap.Entry<K,V> p = new LinkedHashMap.Entry<K,V>(hash, key, value, e); linkNodeLast(p); // 将p链接至双向链表尾部 return p; } // 覆盖(+ 链接p至双向链表尾部),见HashMap.TreeNode.putTreeVal方法 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); linkNodeLast(p); // 将p链接至双向链表尾部 return p; } private void linkNodeLast(LinkedHashMap.Entry<K,V> p) { LinkedHashMap.Entry<K,V> last = tail; tail = p; if (last == null) // 双向链表为空 head = p; else { // 双向链表不为空 p.before = last; last.after = p; } } // 覆盖(HashMap中为noop),见HashMap.removeNode方法 void afterNodeRemoval(Node<K,V> e) { LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after; p.before = p.after = null; if (b == null) // p为头结点 head = a; else b.after = a; if (a == null) // p为尾节点 tail = b; else a.before = b; } // 覆盖(HashMap.Node -> LinkedHashMap.Entry、+ 转移before和after属性),见HashMap.TreeNode.untreeify方法 Node<K,V> replacementNode(Node<K,V> p, Node<K,V> next) { LinkedHashMap.Entry<K,V> q = (LinkedHashMap.Entry<K,V>)p; LinkedHashMap.Entry<K,V> t = new LinkedHashMap.Entry<K,V>(q.hash, q.key, q.value, next); transferLinks(q, t); // before和after属性转移(可能修改双向链表的头尾节点) return t; } // 覆盖(+ 转移before和after属性),见HashMap.treeifyBin方法 TreeNode<K,V> replacementTreeNode(Node<K,V> p, Node<K,V> next) { LinkedHashMap.Entry<K,V> q = (LinkedHashMap.Entry<K,V>)p; TreeNode<K,V> t = new TreeNode<K,V>(q.hash, q.key, q.value, next); transferLinks(q, t); // before和after属性转移(可能修改双向链表的头尾节点) return t; } private void transferLinks(LinkedHashMap.Entry<K,V> src, LinkedHashMap.Entry<K,V> dst) { LinkedHashMap.Entry<K,V> b = dst.before = src.before; LinkedHashMap.Entry<K,V> a = dst.after = src.after; if (b == null) // src为头节点 head = dst; else b.after = dst; if (a == null)// src为尾节点 tail = dst; else a.before = dst; } ... }
3. 迭代器
用LinkedHashMap.Entry.after对双向链表节点进行迭代
// LinkedEntrySet迭代器 final class LinkedEntryIterator extends LinkedHashIterator implements Iterator<Map.Entry<K,V>> { public final Map.Entry<K,V> next() { return nextNode(); } } // LinkedKeySet迭代器 final class LinkedKeyIterator extends LinkedHashIterator implements Iterator<K> { public final K next() { return nextNode().getKey(); } } // LinkedValues迭代器 final class LinkedValueIterator extends LinkedHashIterator implements Iterator<V> { public final V next() { return nextNode().value; } }
// 用LinkedHashMap.Entry的after属性进行迭代 abstract class LinkedHashIterator { LinkedHashMap.Entry<K,V> next; // 下次返回的元素 LinkedHashMap.Entry<K,V> current; // 当前返回的元素 int expectedModCount; LinkedHashIterator() { next = head; expectedModCount = modCount; current = null; } public final boolean hasNext() { return next != null; } final LinkedHashMap.Entry<K,V> nextNode() { LinkedHashMap.Entry<K,V> e = next; if (modCount != expectedModCount) throw new ConcurrentModificationException(); if (e == null) throw new NoSuchElementException(); current = e; next = e.after; return e; } public final void remove() { Node<K,V> p = current; if (p == null) throw new IllegalStateException(); if (modCount != expectedModCount) throw new ConcurrentModificationException(); current = null; K key = p.key; removeNode(hash(key), key, null, false, false); // HashMap.removeNode expectedModCount = modCount; // HashMap.removeNode将使modCount++ } }