//在节点删除后,维护链表,传入删除的节点void afterNodeRemoval(Node<K,V> e) { // unlink //p指向待删除元素,b执行前驱,a执行后驱 LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after; //这里执行双向链表删除p节点操作,很不简单。 p.before = p.after = null; if (b == null) head = a; else b.after = a; if (a == null) tail = b; else a.before = b; }
//在节点被访问后根据accessOrder判断是否需要调整链表顺序void afterNodeAccess(Node<K,V> e) { // move node to last LinkedHashMap.Entry<K,V> last; if (accessOrder && (last = tail) != e) { 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 = b; //这里执行将p放到尾部 if (last == null) head = p; else { p.before = last; last.after = p; } tail = p; ++modCount; } }
void afterNodeInsertion(boolean evict) { // possibly remove eldest LinkedHashMap.Entry<K,V> first; //removeEldestEntry(first)默认返回false,所以afterNodeInsertion这个方法其实并不会执行 if (evict && (first = head) != null && removeEldestEntry(first)) { K key = first.key; removeNode(hash(key), key, null, false, true); } } protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { return false; }
此方法可用来实现LRU,重写removeEldestEntry方法,