条件
- 扩容 resize( ) 时,红黑树拆分成的 树的结点数小于等于临界值6个,则退化成链表。
- 移除元素 remove( ) 时,在removeTreeNode( ) 方法会检查红黑树是否满足退化条件,与结点数无关。如果红黑树根 root 为空,或者 root 的左子树/右子树为空,root.left.left 根的左子树的左子树为空,都会发生红黑树退化成链表。
扩容 resize( ) 的源码分析
- 扩容时如果是红黑树结构会执行红黑树的 split( ) 方法
- split 方法中会初始化生成 loHead 和 hiHead 两个红黑树的头结点(之后会用 low 和 high 表示)
- lc 和 hc 分别为 low 和 high 的元素个数,初始化为0
- 把红黑树中的结点依次添加到 low 和 high 两颗红黑树中,依靠 (e.hash & bit) == 0 的位运算来判断属于哪颗树,bit是传过来的旧数组下标。每颗树元素的增加都会使对应的 lc 或 hc 自增1。
- 生成完 low 和 high 两颗红黑树后,如果对应的元素个数 lc,hc 小于等于6,退化成链表,否则维持红黑树形态。
- low树插入到新数组 tab[index] 的位置上,index是当前红黑树所在旧数组坐标;high树插入到新数组 tab[index + bit] 的位置上,bit是旧数组长度。
static final int UNTREEIFY_THRESHOLD = 6;
else if (e instanceof TreeNode)
((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
final void split(HashMap<K,V