hashmap 源码解析 new HashMap<>(7)
hashmap 实例化有四个构造方法 分别是:
默认构造函数: 最常用
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
指定初始化大小的
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
指定初始化大小和加载因子的:
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);
}
指定map 对象的:不常用
public HashMap(Map<? extends K, ? extends V> m) {
this.loadFactor = DEFAULT_LOAD_FACTOR;
putMapEntries(m, false);
}
一般调用 默认的构造函数 new HashMap<>(),很少用 HashMap(int initialCapacity)
现在来看看 这个构造方法都做了什么操作。
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
传入默认加载因子(DEFAULT_LOAD_FACTOR)和 入参initialCapacity 调用了 HashMap(int initialCapacity, float loadFactor) 方法
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0) // 小于0 抛异常
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY) // 如果大于最大值 设为最大值
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor)) // 验证加载因子 不能为空 也不能小于0
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
// 重点: 计算出map的扩容阈值threshold 大小(下一次扩容是的大小)
// 其实这里面有个细节 : 设置的是扩容阈值 但是在resize() 的时候,又会把 threshold 的值赋给
// newCap (map 的size) 能后设置 新的 threshold 为 0.75(加载因子)*newCap
this.threshold = tableSizeFor(initialCapacity);
}
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 >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
tableSizeFor 返回大于等于且最接近cap 的2的整数次幂的数