源码来源于JDK-11.0.8

/**
* Constructs an empty {@code HashMap} with the specified initial
* capacity and load factor.
*
* @param initialCapacity the initial capacity
* @param loadFactor the load factor
* @throws IllegalArgumentException if the initial capacity is negative
* or the load factor is nonpositive
*/
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);
}
/**
* Constructs an empty {@code HashMap} with the specified initial
* capacity and the default load factor (0.75).
*
* @param initialCapacity the initial capacity.
* @throws IllegalArgumentException if the initial capacity is negative.
*/

public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}

/**
* Constructs an empty {@code HashMap} with the default initial capacity
* (16) and the default load factor (0.75).
*/
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

/**
* Constructs a new {@code HashMap} with the same mappings as the
* specified {@code Map}. The {@code HashMap} is created with
* default load factor (0.75) and an initial capacity sufficient to
* hold the mappings in the specified {@code Map}.
*
* @param m the map whose mappings are to be placed in this map
* @throws NullPointerException if the specified map is null
*/
public HashMap(Map<? extends K, ? extends V> m) {
this.loadFactor = DEFAULT_LOAD_FACTOR;
putMapEntries(m, false);
}

  • initialCapcity:HashMap的初始长度
  • loadFactor: HashMap的负载因子

上面的构造函数主要是1,4个,第2个和第3个构造函数都是依赖于第一个构造函数的

public HashMap(int initialCapacity, float loadFactor)
public HashMap(int initialCapacity)
public HashMap()
public HashMap(Map<? extends K, ? extends V> m)

分析第一个构造函数

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);
}

//-------------------------------------------------
/**
* 特殊声明
* static final int MAXIMUM_CAPACITY = 1 << 30;
* 那么MAXMUM_CAPACITY的值就是 2**30
*/

分析上述代码我们可以得知构造函数流程

  1. 判断初始的容量值是否合理。初始值 < 0,抛出异常。
  2. 判断初始值是否大于最大的容量(1<<30),如果大于最大容量,那么初始容量值就是(2**30)
  3. 判断负载因子的值是否合理,如果为负或者NaN,抛出异常。
  4. 传入负载因子和初始容量,并将初始容量改为2的幂指数
static final int tableSizeFor(int cap) {
int n = -1 >>> Integer.numberOfLeadingZeros(cap - 1);
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

tableSizeFor方法所实现的功能:寻找不小于cap的最小2的幂指数的值(例如:cap=2,不小于2的最小的2的幂指数为2;cap=7,不小于7的最小2的幂指数为8。(Integer.numberOfLeadingZeros的源码解释在另一篇博客里提到过)

第2,3个构造函数

public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

//-------------------------------------------------
/**
* 特殊声明
* static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
* static final float DEFAULT_LOAD_FACTOR = 0.75f;
*/

分析上述代码不难得出,第2,3两个构造函数调用的第一个构造函数。

  • 构造函数2: 构建一个指定initialCapacity大小,loadFactor=0.75的HashMap
  • 构造函数3: 构造一个initailCapacity=16,loadFactor=0.75的HashMap

第4个构造函数

public HashMap(Map<? extends K, ? extends V> m) {
this.loadFactor = DEFAULT_LOAD_FACTOR;
putMapEntries(m, false);
}

构造函数4: 构建一个实现Map接口对象的映射,loadFactor=0.75的HashMap