1、JDK 8 HashMap为啥要引入红黑树?
当HashMap 的 key 冲突过多时,比如我们使用了不好的 hash 算法,导致key冲突率极高,链表里会有很多数据。
但是链表的查找性能很差,所以引入红黑树是为了优化查询性能。
2、JDK 8 HashMap为啥不直接用红黑树?
因为树节点所占用的空间是普通节点的两倍,所以只有当节点足够多的时候,才会使用树节点。
也就是说,最开始使用链表的时候,链表是比较短的,空间占用也是比较少的,查询性能都差不多。
但是当链表越来越长,链表查询越来越慢,这时候才会舍弃链表而使用红黑树,以空间换时间。
所以没有必要一开始就用红黑树,另外,链表较长的情况非常少见。
一开始就使用红黑树反而会导致所有的情况都会占用比链表大2倍的空间,适得其反,这也是一种平衡的策略。
3、为什么链表长度达到8?
因为达到8个元素的时候,概率已经很低了。此时树化,性价比会很高。
既不会因为链表太长(8)导致复杂度加大,也不会因为概率太高导致太多节点树化。
4、为什么红黑树转链表的阈值为6?
主要是因为,如果也将该阈值设置于8,那么当hash碰撞在8时,会反生链表和红黑树的不停相互激荡转换。中间有个差值7可以防止链表和树之间的频繁转换。
假设一下:
如果设计成链表个数超过8则链表转换成树结构,链表个数小于8则树结构转换成链表,
如果HashMap不停的插入,删除元素,链表个数在8左右徘徊,就会频繁的发生红黑树转链表,链表转红黑树,效率会很低下。
5、putVal 方法主要做了这么几件事情
当桶数组 table 为空时,resize()初始化 table查找要插入的键值对是否已经存在,
onlyIfAbsent如果为false且oldValue等于null 则覆盖旧值。
如果不存在,则将键值对链入链表中,如果链表长度达到了8,且数组长度小于64,那么就重新散列。
如果大于64,则创建红黑树判断键值对数量是否大于阈值,大于的话则进行扩容操作。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。