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,则创立红黑树判断键值对数量是否大于阈值,大于的话则进行扩容操作。