HashMap
hashmap什么时候扩容
当我们创建一个集合对象的时候, 其实就是向内存中一次性申请一段空间, 然而这个内存大小是在创建集合对象的时候去指定的, 比如List默认大小是10, HashMap默认大小是16. 如果想要存的数据大于申请容量大小或者到某个阈值的时候, 集合就会动态扩容, List和HashMap其实就是一个数组结构, 扩容时只需要申请更大的内存空间, 然后将数组里的内容拷贝即可.
当HashMap到达临界值的时候就会触发扩容, 这个临界值并不是任意指定也不是容量大小, 他有一个公式: 临界值 = 负载因子 * 容量大小 负载因子(loadFactor)默认值是0.75, 容量大小(capacity)默认值是16 也就是说, 元素个数到达12的时候就会扩容, 扩容大小是原来的2倍.
如果在创建hashmap的时候明确知道自己数据的范围大小, 那么就直接指定想要申请的内存大小,从而避免频繁的内存申请和数据拷贝, 这些都非常影响性能.
hashmap为什么扩容因子是0.75
扩容因子表示hashmap中元素的填充程度, 扩容因子越大, 那么意味着触发扩容因子的元素个数会更多, 虽然空间利用率会随着扩容因子的增大而增加, 但是hash冲突的概率也会增加, 反之,扩容因子越小, hash冲突就越小, 但是对空间的利用率就越小,而且会增加扩容的频率. 因此, 扩容因子本质上就是hash冲突的概率和空间利用率之间的一个平衡.
hashMap是如何解决hash冲突的
当我们通过put来增加元素的时候, hashmap会根据key的hash进行取模运算, 最后将值保存到数组的指定位置, 但是这样的设计方式会导致hash冲突的问题, 所以hashMap引入了链式寻址法来解决hash冲突的问题, hashMap把这些key组成一个单向链表, 使用尾插法,将值保存在链表尾部, 当链表长度大于8并且数组长度大于等于64的时候, hashmap把链表转为红黑树