HashMap的链表长度为8并不是绝对的
HashMap的数据结构
在jdk8之前,HashMap的数据结构还是以数组加链表的方式存储,到8之后呢,由于链表需要迭代查询,链表就需要转红黑树,从而实现时间复杂度上的提升。尽管链表的长度越长,hash冲突概率越小,也无法阻挡官方为了这个细节做出结构上的变化。所以当链表长度达到8时会转成红黑树,但并不是绝对的。
HashMap为什么会快
其实这是一个老生长谈的问题:
- 合理的数据结构:数组、链表、红黑树
- 采用hash算法:第一次放值时,将key的hashcode高16位和低16位做异或求出hash值,和数组最大下标与运算,当再次扩容时使用hash值与旧数组长度与运算,求出新的下标值,存在两种可能性,与运算为0,还是旧数组下标位置,是1,为旧数组下标位置+旧数组长度
- 底层采用位运算:不管是求下标位置还是扩容计算都采用位运算,这也是为什么数组长度为2的n次方的原因之一。
何时转红黑树
当链表长度超过8时,会调用treeifyBin方法,从这个方法可以看出转红黑树时还需要保证数组长度大于等于64,否则会进行resize。
final void treeifyBin(Node<K,V>[] tab, int hash) {
int n, index; Node<K,V> e;
if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
resize();