我们再看看构造方法
构造方法
在这源码中,loadFactor负载因子是一个非常重要的参数,因为他能够反映HashMap桶数组的使用情况, 这样的话,HashMap的时间复杂度就会出现不同的改变。
当这个负载因子属于低负载因子的时候,HashMap所能够容纳的键值对数量就是偏少的,扩容后,重新将键值对 存储在桶数组中,键与键之间产生的碰撞会下降,链表的长度也会随之变短。
但是如果增加负载因子当这个负载因子大于1的时候,HashMap所能够容纳的键值对就会变多,这样碰撞就会增加, 这样的话链表的长度也会增加,一般情况下负载因子我们都不会去修改。都是默认的0.75。
扩容机制
resize()这个方法就是重新计算容量的一个方法,我们看看源码:
所以说在经过resize这个方法之后,元素的位置要么就是在原来的位置,要么就是在原来的位置移动2次幂的位置上。 源码上的注释也是可以翻译出来的
所以说他的扩容其实很有意思,就有了三种不同的扩容方式了,
在HashMap刚初始化的时候,使用默认的构造初始化,会返回一个空的table,并且 thershold为0,因此第一次扩容的时候默认值就会是16. 同时再去计算thershold = DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY = 16*0.75 = 12.
如果说指定初始容量的初始HashMap的时候,那么这时候计算这个threshold的时候就变成了 threshold = DEFAULT_LOAD_FACTOR * threshold(当前的容量)
如果HashMap不是第一次扩容,已经扩容过了,那么每次table的容量
threshold也会变成原来的2倍。
之前看1.7的源码的时候,是没有这个红黑树的,而是在1.8 之后做了相应的优化。 使用的是2次幂的扩展(指长度扩为原来2倍)。 而且在扩充HashMap的时候,不需要像JDK1.7的实现那样重新计算hash,这样子他就剩下了计算hash的时间了。
看完这个源码,翻译了一节节的英文,算是大致明白了一点源码内容了,有什么讨论的问题咱们可以一起讨论一下,感谢观看。