Java 8 HashMap(六)——treeifyBin()树化和treeify()方法

说明看注释

一、treeifyBin方法

    final void treeifyBin(Node<K, V>[] tab, int hash) {
        //n 数组的长度,index 数组位置
        int n, index;
        Node<K, V> e;
        if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY) {
            //如果当前数组为空,或者当前数组容量小于最小树化容量
            //直接扩容不进行树化
            resize();
        } else if ((e = tab[index = (n - 1) & hash]) != null) {
            //当当前找的节点e不为空
            //hd红黑树链表头,红黑树链表尾(红黑树中不仅有维护其所有节点的红黑树结构,还有所有节点的链表结构)
            //所以先将目前节点按链表排列好,在进行红黑树化
            TreeNode<K, V> hd = null, tl = null;
            //遍历列表
            do {
                //将当前e节点装化为TreeNode
                TreeNode<K, V> p = replacementTreeNode(e, null);
                //如果tl不存在
                if (tl == null) {
                    //则p为hd
                    hd = p;
                } else {
                    //若存在则p的前节点指向tl
                    p.prev = tl;
                    //tl的后节点指向p
                    tl.next = p;
                }
                //最后将tl指向p
                tl = p;
            } while ((e = e.next) != null);
            if ((tab[index] = hd) != null) {
                //将hd放在数组上,且hd存在,将链表进行红黑树化
                hd.treeify(tab);
            }
        }
    }

二、treeify方法

        final void treeify(Node<K, V>[] tab) {
            TreeNode<K, V> root = null;
            for (TreeNode<K, V> x = this, next; x != null; x = next) {
                //根据链表进行遍历
                next = (TreeNode<K, V>) x.next;
                x.left = x.right = null;
                if (root == null) {
                    //如果根节点还没设置则当前节点设置为根节点root
                    x.parent = null;
                    //根节点一定是黑色的
                    x.red = false;
                    root = x;
                } else {
                    //获取当前循环节点的key和哈希值
                    K k = x.key;
                    int h = x.hash;
                    Class<?> kc = null;
                    //每次都从根节点开始循环
                    TreeNode<K, V> p = root;
                    for (; ; ) {
                        //遍历当前红黑树
                        int dir;
                        //获得p的hash值和key
                        int ph = p.hash;
                        K pk = p.key;
                        //比较hash值,然后根据比较值dir决定插入左边还是右边
                        if (ph > h) {
                            dir = -1;
                        } else if (ph < h) {
                            dir = 1;
                        } else if ((kc == null && (kc = comparableClassFor(k)) == null) ||
                                (dir = compareComparables(kc, k, pk)) == 0) {
                            //k不是不是课比较类或者比较结果为0,使用tieBreakOrder方法比较
                            dir = tieBreakOrder(k, pk);
                        }
                        TreeNode<K, V> xp = p;
                        p = (dir <= 0) ? p.left : p.right;
                        //仅当当前要插入的位置上没有节点时才进行插入,否则继续向下遍历
                        if (p == null) {
                            //设置父节点
                            x.parent = xp;
                            //根据dir值设置为父节点的左右子节点
                            if (dir <= 0) {
                                xp.left = x;
                            } else {
                                xp.right = x;
                            }
                            //插入成功后平衡红黑树
                            root = balanceInsertion(root, x);
                            //跳出当前循环
                            break;
                        }
                    }
                }
            }
            //确保当前的root是直接落在table数组上的
            moveRootToFront(tab, root);
        }
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值