共同学习Java源代码-数据结构-HashMap(十七)

来源:互联网 发布:php 处理图片 s3 编辑:程序博客网 时间:2024/05/19 17:07
       static int tieBreakOrder(Object a, Object b) {
            int d;
            if (a == null || b == null ||
                (d = a.getClass().getName().
                 compareTo(b.getClass().getName())) == 0)
                d = (System.identityHashCode(a) <= System.identityHashCode(b) ?
                     -1 : 1);
            return d;

        }

这个方法是确定插入顺序的 先比较类名的排名 然后比较对象哈希值的排名 System类的那个方法和hashCode方法返回值是一样的 


        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) {
                    x.parent = null;
                    x.red = false;
                    root = x;
                }
                else {
                    K k = x.key;
                    int h = x.hash;
                    Class<?> kc = null;
                    for (TreeNode<K,V> p = root;;) {
                        int dir, ph;
                        K pk = p.key;
                        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);
        }

这个方法是将链表转换成树的方法 

首先定义根节点root

进入for循环 创建x变量 初始值为本树节点对象 再定义next对象 循环条件是x不为空 x赋next的引用

next赋引用为x的next节点

x的左和右节点都置空

判断如果root为空 说明是第一次遍历 将x的父节点置空 x置为黑树 将x设为root

如果根节点不为空 

将x的键赋给变量k 将x的哈希值赋给临时变量h 定义Class类型kc用来判断节点的类

再进入一个无限的for循环 从root开始遍历

定义临时变量dir 和 ph

将p的键赋给临时变量pk 

将p的哈希值赋给ph 判断ph是否大于h 也就是x的哈希值 dir返回-1 如果小于就返回1 如果等于 就判断如果kc为空也就是第一次循环 且x的键的类型不是Comparable实现类或p的键和x的键比值一样 调用上面那个方法确定dir

将p赋给临时变量xp 

判断如果dir小于等于0且p的左节点为空 或 dir大于0且p的右节点为空

将x的父节点设为p 将x赋给p的左节点或右节点 根据dir值 

然后调用balanceInsertion方法调整root 然后跳出循环

这个嵌套的for循环 其实就是判断出来当前节点不是根节点 就给当前节点找父节点 并确定当前节点是父节点的左还是右节点

跳出所有的循环后 将根节点移动到哈希桶数组中


        final Node<K,V> untreeify(HashMap<K,V> map) {
            Node<K,V> hd = null, tl = null;
            for (Node<K,V> q = this; q != null; q = q.next) {
                Node<K,V> p = map.replacementNode(q, null);
                if (tl == null)
                    hd = p;
                else
                    tl.next = p;
                tl = p;
            }
            return hd;
        }

这个方法是将树降级成链表的方法 不多说了 就是循环遍历树节点 将每个树节点向上转型成普通节点  挨个穿成链表 最后返回首节点


阅读全文
0 0
原创粉丝点击