HashMap中红黑树TreeNode的split()方法源码分析

 spit()方法的作用是将旧数组转移到新数组,split(HashMap<K,V> map, Node<K,V>[] tab, int index, int bit)方法的四个参数
 分别是:当前hashMap对象、新数组、正在遍历的旧数组下标、旧数组的长度。在分析HashMap$TreeNode(既是树又是链表)split()方法的源码时,我们会发现它主要分两部分操作: 
  • 一、数据从旧数组转移到新数组中时,旧数组上的数据会根据(e.hash & bit)是否等于0,重新rehash计算其在数组上的索引位置,分两种情况:
 1、等于0时,则将该树链表头节点放到新数组时的索引位置等于其在旧数组时的索引位置,记为低位区树链表lo。
 2、不等于0时,则将该树链表头节点放到新数组时的索引位置等于其在旧数组时的索引位置再加上旧数组长度,记为高位区树链表hi。
  • 二、当红黑树被split分割开成为两个小红黑树后:
 1、当低位区小红黑树元素个数小于等于6时,开始去树化untreeify操作;
 2、当低位区小红黑树元素个数大于6且高位区红黑树不为null时,开始树化操作(赋予红黑树的特性)
final void split(HashMap<K,V> map, Node<K,V>[] tab, int index, int bit) {
            TreeNode<K,V> b = this;
            // Relink into lo and hi lists, preserving order
            TreeNode<K,V> loHead = null, loTail = null;
            TreeNode<K,V> hiHead = null, hiTail = null;
            int lc = 0, hc = 0;
            for (TreeNode<K,V> e = b, next; e != null; e = next) {
                next = (TreeNode<K,V>)e.next;
                e.next = null;
                if ((e.hash & bit) == 0) {//区分树链表的高低位
                    if ((e.prev = loTail) == null)//低位尾部标记为null,表示还未开始处理,此时e是第一个要处理的低位树链表
                    //节点,故e.prev等于loTail都等于null
                        loHead = e;//低位树链表的第一个树链表节点
                    else
                        loTail.next = e;
                    loTail = e;
                    ++lc;//低位树链表元素个数计数
                }
                else {
                    if ((e.prev = hiTail) == null)
                        hiHead = e;//高位树链表的第一个树链表节点
                    else
                        hiTail.next = e;
                    hiTail = e;
                    ++hc;//高位树链表元素个数计数
                }
            }

            if (loHead != null) {//低位树链表不为null
                if (lc <= UNTREEIFY_THRESHOLD)//低位树链表元素个数若小于等于6
                    tab[index] = loHead.untreeify(map);//开始去树化操作(就是将元素TreeNode节点都转换成Node节点)
                else {
                    tab[index] = loHead;
                    if (hiHead != null) // (else is already treeified) //若高位数链表头节点为空,说明还没有处理完高位
                    //,还不能进行树化操作
                        loHead.treeify(tab);//低位树链表元素个数若大于6且高位树链表头节点不等于null,开始将低位树链表真
                        //正树化成红黑树(前面都只是挂着TreeNode的名号,但实际只是链表结构,还没包含红黑树的特性,
                        //在这里才赋予了它红黑树的特性)
                }
            }
            if (hiHead != null) {//高位树链表不为null
                if (hc <= UNTREEIFY_THRESHOLD)//高位树链表元素个数若小于等于6
                    tab[index + bit] = hiHead.untreeify(map);//开始去树化操作(就是将元素TreeNode节点都转换成Node节点)
                else {
                    tab[index + bit] = hiHead;
                    if (loHead != null) //若低位数链表头节点为空,说明还没有处理完低位,还不能进行树化操作
                        hiHead.treeify(tab);//高位树链表元素个数若大于6且低位树链表头节点不等于null,
                        //开始将高位树链表真正树化成红黑树
                }
            }
        }
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值