HashMap之treeify

20 篇文章 0 订阅

前提

  • jdk1.8之前HashMap的存储方式:链表+hash
  • jdk1.8以后中HashMap的存储方式:链表+hash+红黑树算法

作用

  • 把Node对象转换成TreeNode结构
  • 把链表结构转换成树结构

业务逻辑

  • 1,循环当前链表
  • 1.2,如果是第一个节点,先设置当前对象为根节点
  • 1.3,如果不是根节点,循环当前对象的后面的对象
  • 1.3.1,判断当前子节点是否需要放在左边,还是右边
  • 1.3.2,处理子节点的其他信息,是否为红节点,是否需要旋转(左旋,右旋)
  • 1.4,重置根节点

源码分析

/**
 * Forms tree of the nodes linked from this node.
 * @return root of tree
 */
final void treeify(Node<K,V>[] tab) {
    TreeNode<K,V> root = null;
    //循环当前对象
    for (TreeNode<K,V> x = this, next; x != null; x = next) {
    	//转换成TreeNode对象
        next = (TreeNode<K,V>)x.next;
        x.left = x.right = null;
        //如果是root 是空,证明是第一个对象
        if (root == null) {
        	//设置根节点
            x.parent = null;
            x.red = false;
            root = x;
        }
        //如果是root不是空,根节点已经存在了,处理剩下对象
        else {
            K k = x.key;
            int h = x.hash;
            Class<?> kc = null;
            //对x之后的对象,进行划分左右
            for (TreeNode<K,V> p = root;;) {
                int dir, ph;
                K pk = p.key;
                //判断当前对象是应该划分到左边还是右边 -1放在左边  1放在右边
                if ((ph = p.hash) > h)
                    dir = -1;
                else if (ph < h)
                    dir = 1;
                else if ((kc == null &&
                          (kc = comparableClassFor(k)) == null) ||
                         (dir = compareComparables(kc, k, pk)) == 0)
                    dir = tieBreakOrder(k, pk);

                TreeNode<K,V> xp = p;
                if ((p = (dir <= 0) ? p.left : p.right) == null) {
                    x.parent = xp;
                    //对象进行划分左右
                    if (dir <= 0)
                        xp.left = x;
                    else
                        xp.right = x;
                    //处理当前节点(判断是红色节点,还是黑色节点,是否需要右旋转,左旋转)
                    root = balanceInsertion(root, x);
                    break;
                }
            }
        }
    }
    //再次确定根节点
    moveRootToFront(tab, root);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值