jdk1.8 hashmap.putTreeVal方法解析

本文详细解析了Java中HashMap使用红黑树进行插入操作的内部机制,包括节点比较、遍历查找、节点平衡调整及插入过程。通过具体代码分析,深入理解红黑树在HashMap中的应用。
final TreeNode<K,V> putTreeVal(HashMap<K,V> map, Node<K,V>[] tab,
                       int h, K k, V v) {
    Class<?> kc = null;//k的类型
    boolean searched = false;//是否遍历过树了
    TreeNode<K,V> root = (parent != null) ? root() : this;//树的根节点
    for (TreeNode<K,V> p = root;;) {
        int dir, ph; K pk;//dir树的左右方向,ph当前节点的hash,pk当前节点的key值
        if ((ph = p.hash) > h)
            dir = -1;
        else if (ph < h)
            dir = 1;
        else if ((pk = p.key) == k || (k != null && k.equals(pk)))
            return p;
        //根据当前节点key值、hash和传进来要插入的key值、hash一般都能得到一个左或右方向
        //或者当前节点key值、hash和传进来要插入的key值、hash相等或equals
        //但是还有一种情况就是hash相等key不equals
        else if ((kc == null &&
                  (kc = comparableClassFor(k)) == null) ||
                 (dir = compareComparables(kc, k, pk)) == 0) {
            //走到这里说明:指定key没有实现comparable接口
            //或者实现了comparable接口并且和当前节点的键对象比较之后相等
            /**searched 标识是否已经对比过当前节点的左右子节点了
			* 如果还没有遍历过,那么就递归遍历对比,看是否能够得到那个键对象equals相等的节点
			* 如果得到了键的equals相等的的节点就返回
			* 如果还是没有键的equals相等的节点,那说明应该创建一个新节点了
			* find(h, k, kc)递归、while遍历ch的所有节点直到找到与k equals的节点否则就返回空
			*/
            if (!searched) {
                TreeNode<K,V> q, ch;
                searched = true;
                if (((ch = p.left) != null &&
                     (q = ch.find(h, k, kc)) != null) ||
                    ((ch = p.right) != null &&
                     (q = ch.find(h, k, kc)) != null))
                    return q;
            }
            // 走到这里就说明,遍历了所有子节点也没有找到和当前键equals相等的节点
            dir = tieBreakOrder(k, pk);//把两个key的object的hashcode()方法生成的hashcode比较决定方向
        }

        TreeNode<K,V> xp = p; // 定义xp指向当前节点
        /*
        * 如果dir小于等于0,那么看当前节点的左节点是否为空,如果为空,就可以把要添加的元素作为当前节点的左节点,如果不为空,还需要下一轮继续比较
        * 如果dir大于等于0,那么看当前节点的右节点是否为空,如果为空,就可以把要添加的元素作为当前节点的右节点,如果不为空,还需要下一轮继续比较
        * 如果以上两条当中有一个子节点不为空,这个if中还做了一件事,那就是把p已经指向了对应的不为空的子节点,开始下一轮的比较
        */
        if ((p = (dir <= 0) ? p.left : p.right) == null) {  
            // 如果恰好要添加的方向上的子节点为空,此时节点p已经指向了这个空的子节点
            Node<K,V> xpn = xp.next; // 获取当前节点的next节点
            TreeNode<K,V> x = map.newTreeNode(h, k, v, xpn); // 创建一个新的树节点
            if (dir <= 0)
                xp.left = x;  // 左孩子指向到这个新的树节点
            else
                xp.right = x; // 右孩子指向到这个新的树节点
            xp.next = x; // 链表中的next节点指向到这个新的树节点
            x.parent = x.prev = xp; // 这个新的树节点的父节点、前节点均设置为 当前的树节点
            if (xpn != null) // 如果原来的next节点不为空
                ((TreeNode<K,V>)xpn).prev = x; // 那么原来的next节点的前节点指向到新的树节点
            moveRootToFront(tab, balanceInsertion(root, x));// 重新平衡,以及新的根节点置顶
            return null; // 返回空,意味着产生了一个新节点
        }
    }
}
### 回答1JDK 1.8 tar.gz是指Java Development Kit(JDK)的1.8版本的压缩文件格式为tar.gz。 JDK是Java开发工具包的缩写,它是由Oracle公司提供的用于开发和运行Java应用程序的软件包。JDK 1.8是Java的第8个主要版本,在其发布时具有重要的新特性和改进。 tar.gz是一种常见的压缩文件格式,在Linux和Unix系统中广泛使用。它是通过将文件和目录打包成一个tar文件,然后使用gzip进行压缩而创建的。tar.gz文件既可以用于文件的备份,也可以用于文件的传输和分发。 JDK 1.8 tar.gz文件通常用于安装JDK 1.8版本。要使用JDK 1.8,首先需要下载对应的tar.gz文件,然后解压缩该文件。解压缩后,会得到一个包含JDK 1.8所有必要文件的目录结构。 安装JDK 1.8需要根据操作系统的不同执行不同的步骤。在Linux和Unix系统上,可以通过设置环境变量来配置JDK 1.8的路径,以便可以在终端中直接使用javac和java命令。 JDK 1.8提供了许多新特性,包括Lambda表达式、方法引用、函数式接口、默认方法等。这些功能使得Java编程更加简洁高效。因此,JDK 1.8 tar.gz文件的下载和安装对于Java开发人员来说非常重要。 ### 回答2: JDK 1.8 tar.gz 是指 Java Development Kit 1.8 的压缩文件格式。JDK 是 Java 开发工具包的缩写,是用于开发和编译 Java 程序的软件包。1.8 表示 JDK 的版本号,即 JDK 1.8 代表 Java 开发工具包的第八个主要版本。tar.gz 是常见的文件压缩格式,其中 tar 表示归档(Archive),gz 表示使用 Gzip 压缩算法进行压缩。 JDK 1.8 tar.gz 文件通常包含了 JDK 1.8 的所有组件和库,可以在 Linux 或类似操作系统上使用。通过解压这个压缩文件,可以获得 JDK 1.8 的文件目录结构,包括 Java 编译器、运行时环境、开发工具和相关库等。这些文件可以帮助开发者在其计算机上进行 Java 编程和应用的开发、测试和部署。 要使用 JDK 1.8 tar.gz 文件,首先需要将其解压缩到目标文件夹。可以使用解压缩工具如 tar 命令来进行解压缩。解压后,可以设置环境变量,指向解压后的 JDK 1.8 文件夹,这样就可以在命令行或 IDE 中使用 JDK 1.8 的命令和工具。 JDK 1.8 引入了许多新的特性和改进,例如 Lambda 表达式、函数式接口、Stream API、新的时间日期 API 等等。这些新特性可以提高开发效率、简化代码编写,并且使得 Java 在处理并发、函数式编程等方面变得更强大和灵活。 总之,JDK 1.8 tar.gz 是 Java Development Kit 1.8 的压缩文件格式,包含了 Java 开发工具包的各个组件和库,可以帮助开发者进行 Java 开发和应用的编译、测试和部署。 ### 回答3: JDK是Java Development Kit的缩写,是用于Java程序开发的软件开发工具包。JDK1.8tar.gz是指JDK1.8版本的压缩文件。 tar.gz是一种常见的文件压缩格式,常用于Linux和Unix系统。tar是指tarball,是一种对多个文件进行打包的工具。gz是指gzip,是一种数据压缩程序。tar.gz就是将多个文件打包成tar格式后再使用gzip进行压缩得到的文件。 JDK1.8tar.gz文件可以通过解压缩工具进行解压缩,得到包含JDK1.8版本所有文件和目录的文件夹。这些文件和目录包括JDK的运行环境、编译器、调试工具等,可以用于开发和运行Java程序。 JDK1.8版本是Java的其中一个重要版本,它提供了许多新的特性和改进,包括Lambda表达式、函数式编程、Stream API等。使用JDK1.8版本可以更加方便地开发和管理Java程序,提高程序的性能和效率。 总之,JDK1.8tar.gz是用于Java程序开发的JDK1.8版本的压缩文件,可以通过解压缩得到JDK1.8的所有文件和目录,用于开发和运行Java程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值