Java LinkedHashMap工作原理及实现

发表于:2016-3-24 10:01

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Yikun    来源:51Testing软件测试网采编

  afterNodeAccess函数
void afterNodeAccess(Node<K,V> e) { // move node to last
LinkedHashMap.Entry<K,V> last;
// 如果定义了accessOrder,那么就保证最近访问节点放到最后
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;
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
tail = p;
++modCount;
}
}
  就是说在进行put之后就算是对节点的访问了,那么这个时候就会更新链表,把最近访问的放到最后,保证链表。
  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);
  }
  }
  如果用户定义了removeEldestEntry的规则,那么便可以执行相应的移除操作。
  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;
  }
  这个函数是在移除节点后调用的,就是将节点从双向链表中删除。
  我们从上面3个函数看出来,基本上都是为了保证双向链表中的节点次序或者双向链表容量所做的一些额外的事情,目的就是保持双向链表中节点的顺序要从eldest到youngest。
  3. put和get函数
  put函数在LinkedHashMap中未重新实现,只是实现了afterNodeAccess和afterNodeInsertion两个回调函数。get函数则重新实现并加入了afterNodeAccess来保证访问顺序,下面是get函数的具体实现:
  public V get(Object key) {
  Node<K,V> e;
  if ((e = getNode(hash(key), key)) == null)
  return null;
  if (accessOrder)
  afterNodeAccess(e);
  return e.value;
  }
  值得注意的是,在accessOrder模式下,只要执行get或者put等操作的时候,就会产生structural modification。官方文档是这么描述的:
  A structural modification is any operation that adds or deletes one or more mappings or, in the case of access-ordered linked hash maps, affects iteration order. In insertion-ordered linked hash maps, merely changing the value associated with a key that is already contained in the map is not a structural modification. In access-ordered linked hash maps, merely querying the map with get is a structural modification.
  不要犯了像ConcurrentModificationException with LinkedHashMap类似的问题。
  总之,LinkedHashMap不愧是HashMap的儿子,和老子太像了,当然,青出于蓝而胜于蓝,LinkedHashMap的其他的操作也基本上都是为了维护好那个具有访问顺序的双向链表。:-)
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号