加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

3分钟让你明白:HashMap之红黑树树化过程

发布时间:2019-10-13 10:53:12 所属栏目:建站 来源:追逐仰望星空
导读:01 概述 HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型。随着JDK(Java Developmet Kit)版本的更新,JDK1.8对HashMap底层的实现进行了优化,例如引入红黑树的数据结构和扩容的优化等。本文主要分析一下HashMap中红黑树树化的过程。 02

我们看一下treeify代码

  1. final void treeify(Node<K, V>[] tab) 
  2.  { 
  3.  TreeNode<K, V> root = null; 
  4.  // 以for循环的方式遍历刚才我们创建的链表。 
  5.  for (TreeNode<K, V> x = this, next; x != null; x = next) 
  6.  { 
  7.  // next向前推进。 
  8.  next = (TreeNode<K, V>) x.next; 
  9.  x.left = x.right = null; 
  10.  // 为树根节点赋值。 
  11.  if (root == null) 
  12.  { 
  13.  x.parent = null; 
  14.  x.red = false; 
  15.  root = x; 
  16.  } else 
  17.  { 
  18.  // x即为当前访问链表中的项。 
  19.  K k = x.key; 
  20.  int h = x.hash; 
  21.  Class<?> kc = null; 
  22.  // 此时红黑树已经有了根节点,上面获取了当前加入红黑树的项的key和hash值进入核心循环。 
  23.  // 这里从root开始,是以一个自顶向下的方式遍历添加。 
  24.  // for循环没有控制条件,由代码内break跳出循环。 
  25.  for (TreeNode<K, V> p = root;;) 
  26.  { 
  27.  // dir:directory,比较添加项与当前树中访问节点的hash值判断加入项的路径,-1为左子树,+1为右子树。 
  28.  // ph:parent hash。 
  29.  int dir, ph; 
  30.  K pk = p.key; 
  31.  if ((ph = p.hash) > h) 
  32.  dir = -1; 
  33.  else if (ph < h) 
  34.  dir = 1; 
  35.  else if ((kc == null && (kc = comparableClassFor(k)) == null) 
  36.  || (dir = compareComparables(kc, k, pk)) == 0) 
  37.  dir = tieBreakOrder(k, pk); 
  38.  // xp:x parent。 
  39.  TreeNode<K, V> xp = p; 
  40.  // 找到符合x添加条件的节点。 
  41.  if ((p = (dir <= 0) ? p.left : p.right) == null) 
  42.  { 
  43.  x.parent = xp; 
  44.  // 如果xp的hash值大于x的hash值,将x添加在xp的左边。 
  45.  if (dir <= 0) 
  46.  xp.left = x; 
  47.  // 反之添加在xp的右边。 
  48.  else 
  49.  xp.right = x; 
  50.  // 维护添加后红黑树的红黑结构。 
  51.  root = balanceInsertion(root, x); 
  52.   
  53.  // 跳出循环当前链表中的项成功的添加到了红黑树中。 
  54.  break; 
  55.  } 
  56.  } 
  57.  } 
  58.  } 
  59.  // Ensures that the given root is the first node of its bin,自己翻译一下。 
  60.  moveRootToFront(tab, root); 
  61.  } 

第一次循环会将链表中的首节点作为红黑树的根,而后的循环会将链表中的的项通过比较hash值然后连接到相应树节点的左边或者右边,插入可能会破坏树的结构所以接着执行balanceInsertion。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读