推荐阅读时间:10分钟
简介
Java8的最大特性是使用红黑树结构来存储每个(桶)bucket中的数据(当链表长度超过8时)。
为什么引入红黑树呢?其实正常情况下,平均每个桶中应该只会有不到1个数据,但当发生大量Hash碰撞时,每个桶中的数据也将会大量增加,这将会影响到数据的查询速度。在Java7中,每个桶使用链表存储数据,查找数据采用遍历的方式,查询时间复杂度为O(n)。Java7中为了避免大量Hash碰撞的问题,引入了hashseed方式,增强了Hash函数的散列性。但是randomHashSeed方法调用的next方法在多线程运算时存在性能问题(待考证),故在Java8中被弃用。Java8中换了一个思路:使用红黑树来提高查找速度(O(logN)),即使发生大量hash碰撞也不会造成性能影响,这便是红黑树由来的原因。
Java7的HashMap一共有接近1200行代码,而到了Java8直接增加到了2400行,减去全局变量前新加的100行注释,相差1100行。其中TreeNode(红黑树)实现部分有600行代码,再加上其他方法对红黑树的适应性改动,可见红黑树部分是Java8 HashMap的主要改动。
详情
继承关系如下:
TreeNode继承了LinkedHashMap.Entry,LinkedHashMap.Entry继承了HashMap.Node,而Node其实就是上个版本的Entry(链表)结构。此处有个疑惑:TreeNode并没有使用LinkedHashMap.Entry的before和after字段,不知道为啥不直接继承Node类。
字段和构造函数如下:
1 | static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> { |
红黑树全部方法如下:
1 | /** |
Java8的HashMap解读暂告一段落,下期继续探讨其他特性,希望不要太久😂
https://y.qq.com/n/yqq/song/004dbfuf1jEjpI.html#stat=y_new.index.new_song.songname