HashMap之红黑树详解

Java 中的 HashMap 采用链表法来解决哈希冲突HashMap 原理,即具有相同桶下标的键值对使用一个链表储存。当链表变长时,查找和添加(需要确定 key 是否已经存在)都需要遍历这个链表,速度会变慢。JDK 1.8 后加入了链表转换为红黑树的机制,但是红黑树的转换并不是一个廉价的操作,只有当链表长度大于等于 TREEIFY_THRESHOLD 才会 treeify。

    /**
     * The bin count threshold for using a tree rather than list for a
     * bin.  Bins are converted to trees when adding an element to a
     * bin with at least this many nodes. The value must be greater
     * than 2 and should be at least 8 to mesh with assumptions in
     * tree removal about conversion back to plain bins upon
     * shrinkage.
     */
    static final int TREEIFY_THRESHOLD = 8;

TREEIFY_THRESHOLD 默认为 8,putVal() 源码如下:

    if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
        treeifyBin(tab, hash);

实际上并不是只要链表长度大于 8 就会 treeify。当 table.length(桶的个数)小于 MIN_TREEIFY_CAPACITY 时会优先扩容而不是转换为红黑树。

以 jdk1.8 为例,打开 HashMap 的源码部分,红黑树内部类 TreeNode 属性分析:

static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
   
		//指向父节点的指针
		TreeNode<K,V> parent;
		//指向左孩子的指针
 TreeNode<K,V> left;
		//指向右孩子的指针
 TreeNode<K,V> right;
		//前驱指针,跟next属性相反的指向
 TreeNode<K,V> prev;
		//是否为红色节点
 boolean red;
		......
}

左旋方法 rotateLeft 如下:

/*
 * 左旋逻辑
 */
static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root,
 TreeNode<K,V> p) {
   
			//root:表示根节点
			//p:表示要调整的节点
			//r:表示p的右节点
			//pp:表示p的parent节点
			//rl:表示p的右孩子的左孩子节点
 TreeNode<K,V> r, pp, rl;
			//r判断,如果r为空则旋转没有意义
 if (p != null && (r = p.right) != null) {
   
				//多个等号的连接操作从右往左看,设置rl的父亲为p
 if ((rl = p.right = r
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛战士从不脱下面具

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值