【java源码一带一路系列】之LinkedHashMap.afterNodeAccess()

发布时间:2019-11-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了【java源码一带一路系列】之LinkedHashMap.afterNodeAccess()脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

本文以jdk1.8中LinkedHashMap.afterNodeAccess()方法为切入点,分析其中难理解、有价值码片段(类似源码查看是ctrl+鼠标左键的过程)。观光线路图:afterNodeAccess() --> afterNodeinsertion() --> removeEldestEntry() --> afterNodeRemoval() --> internalWrITeEntries() ...

☞ afterNodeAccess()

void afterNodeAccess(Node<K,V> e) { // move node to last     LinkedHashMap.Entry<K,V> last;     if (accessOrder &amp;& (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;         if (last == null)             head = p;         else {             p.before = last;             last.after = p;         }         tail = p;         ++modCount;     } }  //////////////////////////////// 涉及变量如下:  /**  * The head (eldest) of the doubly linked list.  */ transient LinkedHashMap.Entry<K,V> head;  /**  * The tail (youngest) of the doubly linked list.  */ transient LinkedHashMap.Entry<K,V> tail;  /**  * The iteration ordering method for this linked hash map: <tt>true</tt>  * for access-order, <tt>false</tt> for insertion-order.  *  * @serial  */ final boolean accessOrder;

上回在HashMap.afterNodeAccess()中说道,“是为LinkedHashMap留的后路”。如今行至于此,当观赏一方。首先需要了解的是LinkedHashMap相比HashMap多了有序性,由双向链表(before,after)实现。源码出现了一些全局变量:

accessOrder:true:按访问顺序排序(LRU),false:按插入顺序排序

head、tail:存放链表首尾

可见仅有accessOrder为true时,且访问节点不等于尾节点时,该方法才有意义。通过before、after重定向,将新访问节点链接为链表尾节点。

@H_360_88@☞ afterNodeInsertion()
void afterNodeInsertion(boolean evict) { // possibly remove eldest     LinkedHashMap.Entry<K,V> first;     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; }

细心的你也花现了吧。afterNodeInsertion()由于removeEldestEntry()所返回的false无执行意义。也就意味着如果想要让它有意义必须重写removeEldestEntry()。

如,使用LinkedHashMaP实现一个简单的LRU(Least Recently Used)Cache。那么就应该重写removeEldestEntry(),当超出缓存容器大小时移除最老的首节点(这里不考虑并发问题,如下):

@Override   public boolean removeEldestEntry(Map.Entry<K, V> eldest){            return size() > capacity;           }  

☞ afterNodeRemoval()

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

afterNodeRemoval()方法相对简单,就是在删除后处理其对应链表前后关系(刨掉一截)。

☞ internalWriteEntries()

LinkedHashMap源码阅读总体门槛相对而言比HashMap,毕竟大多数底层put,get都由HashMap实现了。internalWriteEntries()相对来说比较突兀,如果你知道它在哪里起着什么样神秘的作用请在评论里告诉在下吧。[比心&#x2764;]

void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException {     for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after) {         s.writeObject(e.key);         s.writeObject(e.value);     } }

可通过这篇文章理解创建一个LinkedHashMap实例过程(图):

Java_LinkedHashMap工作原理 2017-05-04;

往期线路回顾:

【java源码一带一路系列】之HashMap.putAll()
【java源码一带一路系列】之HashMap.putVal()
【java源码一带一路系列】之HashMap.compute()

脚本宝典总结

以上是脚本宝典为你收集整理的【java源码一带一路系列】之LinkedHashMap.afterNodeAccess()全部内容,希望文章能够帮你解决【java源码一带一路系列】之LinkedHashMap.afterNodeAccess()所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。