版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ocp114/article/details/82889150
HashMap 的实例化其实没做什么,主要是一些基础参数的赋值
那么来一个一个看看
一、默认的方式
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR;
}
简单地使用了默认装载因子 (0.75)
参数变化:size = 0, modCount = 0, threshold = 0, loadFactor = 0.75
二、指定容量/装载因子的方式
// 指定容量的方式
public HashMap(int initialCapacity) {
// 指定初始化容量为 initialCapacity, 装载因子使用默认的 DEFAULT_LOAD_FACTOR
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
// 指定初始容量和装载因子的方式
public HashMap(int initialCapacity, float loadFactor) {
// 判断容量是否非法
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);
// 如果指定容量超过 HashMap 的 默认最大容量,则使用默认最大容量来初始化
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 对象中传值过来,创建一个新的 HashMap
public HashMap(Map<? extends K, ? extends V> m) {
// 同样适用默认装载因子
this.loadFactor = DEFAULT_LOAD_FACTOR;
// 转移数据
putMapEntries(m, false);
}
// 复制转移 map 元素的方法
final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
int s = m.size();
// 判断原来的 m 是否有数据,有数据的话就需要开始初始化 table 并把数据加进去了
if (s > 0) {
// 如果是第一次初始化 table,则先计算扩容阈值,方便 put 操作时扩容
if (table == null) {
float ft = ((float)s / loadFactor) + 1.0F;
int t = ((ft < (float)MAXIMUM_CAPACITY) ? (int)ft : MAXIMUM_CAPACITY);
if (t > threshold) threshold = tableSizeFor(t);
// 判断是否需要扩容
}else if (s > threshold) resize();
// 把数据转移到 HashMap 中
for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
K key = e.getKey();
V value = e.getValue();
putVal(hash(key), key, value, false, evict);
}
}
}