hashmap构造函数
hashmap的构造函数有四种(jdk1.8):
先上源码,然后再一一解释
// 方式一:
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
}
//方式二:
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
//方式三:
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
//方式四:
public HashMap(Map<? extends K, ? extends V> m) {
this.loadFactor = DEFAULT_LOAD_FACTOR;
putMapEntries(m, false);
}
initialCapacity:初始容量
loadFactor:负载因子
threshold :阈值
方式四:是拷贝别的hashmap的形式(这里不多说,一般用不着吧)
方式二:底层调用了方式一,底层完全一致。
方式一:initialCapacity、loadFactor 两个参数
这里会对 这两个参数做一些判断处理。
需要注意的是:this.threshold = tableSizeFor(initialCapacity);
这里我们看到初始化的并不是容量,而是一个阈值,这里虽然此处初始化的是阈值,但后面初始化table的时候会将其用于table.length,同时会重置阈值=initialCapacity* loadFactor ; (懒初始化,避免浪费内存);
tableSizeFor() 方法:是对初始化容量的处理,因为hashmap的容量必须要2的整数次幂,这个方法底层实现是返回了大于等于当前指定初始容量的2的整数次幂。
举个栗子:
Map map = new HashMap(1000);
此时 table.length = 2^10 = 1024;
threshold = 1024 * 0.75 = 768;
// 在存第769个元素的时候扩容(关于扩容可以看我下一篇文章)
方式三:我们经常用到的,无参,默认构造函数
这种方式会用默认的 initialCapacity:16,和默认的loadFactor :0.75
hashmap初始化
而咱们知道,这些构造函数并没有对table 进行初始化,那么在什么时候才对table进行从初始化呢?
这就涉及到上面提到的懒初始化,table会在第一次put的时候,调用resize 进行初始化