1. LinkedHashMap
LinkedHashMap继承自HashMap,通过覆盖HashMap的一些方法,而在其内部维护了一个双向链表
1)get(覆盖)、afterNodeAccess、afterNodeInsertion(覆盖)和removeEldestEntry的组合可实现LRU(Least Recently Used)算法:继承LinkedHashMap,accessOrder置为true且覆盖removeEldestEntry方法
2)覆盖newNode、newTreeNode和afterNodeRemoval:在添加和删除节点时对双向链表进行维护
3)覆盖replacementNode、replacementTreeNode:在扩容分割红黑树时对双向链表进行维护
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> { static class Entry<K,V> extends HashMap.Node<K,V> { // HashMap.TreeNode继承此类 Entry<K,V> before, after; // 节点前置和后置节点(TreeNode中为prev和next) Entry(int hash, K key, V value, Node<K,V> next) { super(hash, key, value, next); } } 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判断) 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) void afterNodeAccess(Node<K,V> e) { // 在访问e后,将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.before == null(p为头结点) head = a; else // p.before != null b.after = a; if (a != null) // p.after != null a.before = b; else // p.after == null(p为尾节点???tail != e) last = b; if (last == null) // 会出现???在多线程环境下??? head = p; else { p.before = last; // p.before = tail last.after = p; // tail.after = p } tail = p; ++modCount; } } // 覆盖(HashMap中为noop) void afterNodeInsertion(boolean evict) { // removeEldestEntry 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); // 删除head节点 } } // 覆盖(new HashMap.Node -> new LinkedHashMap.Entry、+ 链接p至双向链表尾部) Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) { // HashMap.putVal方法中 LinkedHashMap.Entry<K,V> p = new LinkedHashMap.Entry<K,V>(hash, key, value, e); linkNodeLast(p); // 将p链接至双向链表尾部 return p; } // 覆盖(+ 链接p至双向链表尾部) TreeNode<K,V> newTreeNode(int hash, K key, V value, Node<K,V> next) { // HashMap.TreeNode.putTreeVal方法中 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) 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.before == null(p为头结点) head = a; else // p.before != null b.after = a; if (a == null) // p.after == null(p为尾节点) tail = b; else // p.after != null a.before = b; } // 覆盖(new HashMap.Node -> new LinkedHashMap.Entry、+ 转移before和after属性) Node<K,V> replacementNode(Node<K,V> p, Node<K,V> next) { // HashMap.TreeNode.untreeify方法中 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); // 将q中的before和after属性转移到t中(可能修改双向链表的头尾节点) return t; } // 覆盖(+ 转移before和after属性) TreeNode<K,V> replacementTreeNode(Node<K,V> p, Node<K,V> next) { // HashMap.TreeNode.treeify方法中 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); // 将q中的before和after属性转移到t中(可能修改双向链表的头尾节点) 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.before == null head = dst; else // source.beore != null b.after = dst; if (a == null)// src.after == null tail = dst; else// src.after != null a.before = dst; } ... ... }
2. 迭代器
在LinkedHashMap中的双向链表中迭代(Entry.after属性)
// LinkedEntrySet(entrySet方法)迭代器 final class LinkedEntryIterator extends LinkedHashIterator implements Iterator<Map.Entry<K,V>> { public final Map.Entry<K,V> next() { return nextNode(); } } // LinkedKeySet(keySet方法)迭代器 final class LinkedKeyIterator extends LinkedHashIterator implements Iterator<K> { public final K next() { return nextNode().getKey(); } } // LinkedValues(values方法)迭代器 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; // 下次调用next方法时返回的元素 LinkedHashMap.Entry<K,V> current; // 当前next方法返回的元素 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; // 记录next if (modCount != expectedModCount) throw new ConcurrentModificationException(); if (e == null) throw new NoSuchElementException(); current = e; // current = next next = e.after; // next = next.after return e; // current } public final void remove() { Node<K,V> p = current; if (p == null) throw new IllegalStateException(); if (modCount != expectedModCount) throw new ConcurrentModificationException(); current = null; // current置空 K key = p.key; removeNode(hash(key), key, null, false, false); // HashMap.removeNode -> LinkedHashMap.afterNodeRemoval expectedModCount = modCount; } }