Java集合---HashMap
源码顶部注释:
关于这两个参数值的设定界限:
\1. initialCapacity是map的初始化容量,initialCapacity > MAXIMUM_CAPACITY,表明map的最大容量是1<<30,也就是1左移30位,每左移一位乘以2,所以就是1*2^30=1073741824.
\2. loadFactor是map的负载因子,loadFactor <= 0 || Float.isNaN(loadFactor),表明负载因子要大于0,且是非无穷大的数字。
负载因子为什么会影响HashMap性能
首先回忆HashMap的数据结构,
我们都知道有序数组存储数据,对数据的索引效率都很高,但是插入和删除就会有性能瓶颈(回忆ArrayList),
链表存储数据,要一次比较元素来检索出数据,所以索引效率低,但是插入和删除效率高(回忆LinkedList),
两者取长补短就产生了哈希散列这种存储方式,也就是HashMap的存储逻辑.
而负载因子表示一个散列表的空间的使用程度,有这样一个公式:initailCapacity*loadFactor=HashMap的容量。(HashMap实际存储的容量)
所以负载因子越大则散列表的装填程度越高,也就是能容纳更多的元素,元素多了,链表大了,所以此时索引效率就会降低。
反之,负载因子越小则链表中的数据量就越稀疏,此时会对空间造成烂费,但是此时索引效率高。
如何科学设置 initailCapacity , loadFactor 的值
HashMap有三个构造函数,可以选用无参构造函数,不进行设置。默认值分别是16和0.75.
官方的建议是initailCapacity设置成2的n次幂,laodFactor根据业务需求,如果迭代(索引使用)性能不是很重要,可以设置大一下。
哈希冲突 的解决方法
发送哈希冲突时,HashMap 的解决方法是将相同映射地址的元素连成一条链表,如果链表的长度大于8时,且数组的长度大于64则会转换成红黑树数据结构。
put()
我们可以简单总结出HashMap:
- 无序,允许为null,非同步,非线程安全;
- 它是集合中最常用的
Map
集合类型,底层由数组 + 链表 + 红黑树
组成; - 初始容量和装载因子对HashMap影响挺大的,设置小了不好,设置大了也不好
- 插入元素时,通过计算元素的
哈希值
,通过哈希映射函数转换为数组下标
;查找元素时,同样通过哈希映射函数得到数组下标定位元素的位置