HashMap中有一个有参的构造方法,传递的参数是map初始化的容量。那么给定的参数,HashMap就一定给分配参数对应的容量吗?比如,我传7进去,HashMap就会给分配7个空间吗 ?
答案是:否
因为 HashMap分配的容量可能大于入参,可能小于入参,可能等于入参。为什么会这样?一点点看
HashMap的构造方法
HashMap有四个构造方法
- public HashMap() 默认构造方法,默认初始容量为16,加载因子为0.75f
- public HashMap(int initialCapacity) 指定初始容量的构造方法,加载因子为默认的0.75f
- public HashMap(int initialCapacity, float loadFactor) 指定初始容量和默认加载因子的初始方法
- public HashMap(Map<? extends K, ? extends V> m) 以子map为入参,构造新的hashmap
上面有提到HashMap中两个非常关键的变量,容量和加载因子
容量:capacity HashMap分配的空间个数大小,如果不指定,则默认为16,即HashMap无参构造方法构造出来的map的容量大小。
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
装载因子:load factor 用来表示HashMap中元素的填满的程度,loadFactor的默认值为0.75f。
/**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
如果一个map的size大于临界值时,HashMap会自动扩容,将当前容量扩一倍出来,并重新计算每个对象的位置并存放。
加载因子,是hashmap在扩容时需要的,表示Hsah表中元素的填满的程度。待hashmap中存放的对象数量大于等于map容量*加载因子时,hashmap会自动扩容,将map的容量扩大一倍,并将之前的对象重新进行hash寻址,并存放到新的地址中。
加载因子越大,填满的元素越多,空间利用率越高,但是冲突的机会增大;加载因子越小,填满的元素越少,冲突的机会越小,但空间浪费增多。hash值冲突时,会将对象在同一位置存放链表,增加了数据结构的复杂性。冲突的机会越大,则查找的成本越高;冲突的机会越小,查找的成本越小,换言之,查找时间就越小,更快一些。
必须在 "冲突率"与"空间利用率"之间寻找一种平衡与折衷, Java默认的容量设置为16,默认的加载因子设置为0.75。
临界值:threshold 当实际K-V个数超过threshold时,HashMap会将容量扩容,threshold=容量*加载因