hashMap(链式数组结构:查询快,插入慢):
以其中一个构造函数为例:public HashMap(int initialCapacity, float loadFactor)
initialCapacity → 初始容量,使用无参构造方法时,默认为16
loadFactor → 加载因子,使用无参构造方法时,默认0.75f
1.初始容量的计算方法为:
(元素个数/加载因子+1),离这个值最近的大于或者等于此值的二的幂次。es:6 → 8
源码java8的优化算法如下:
static final int tableSizeFor(int cap){
int n = cap-1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n<0)?1:(n>=1<<30)?1<<30:n+1;
}
此算法先将原值减一为了防止类似于8的二进制1000 最后算出来的结果为16;
算法是将最高位的1后面的值均变为1,最后加1 ,就得到了2的整数次幂的值了
解析:hashmap底层存储的是哈希表,存储的是键值对的类型,它需要通过一定的计算才可以确定数据再哈希表中的存储位置
这种数据容易出现两种问题
①如果空间利用率高,那么经过哈希算法计算存储位置时,就会发现很多位置已经有数据了(哈希冲突)
②如果为了避免冲突,从而增加数组容量,那么就会导致空间利用率不高
加1的原因时因为扩容是在插入后执行的,如若不加1,在插入最后一条数据的时候就会触发扩容,然后我们实际在此扩容后并没有其他数据需要插入,从而产生了不必要的扩容操作。
2.加载因子
加载因子是决定扩容长度主要因素之一
加载因子越大,填满的元素越多,空间利用率越高,但发生冲突的几率越高
加载因子越小,填满的元素越少,发生冲突的几率变低了,但是空间利用率也会变低,而且会增加扩容的次数
最终经过计算,得到了一个时间和空间的折中值0.75
关于LinkedHashMap
accessOrder false: 基于插入顺序 true: 基于访问顺序
加载因子=填入表中元素个数/散列表的长度
https://blog.csdn.net/u013256816/article/details/106866157