2 HashMap 的例項化方法
阿新 • • 發佈:2018-12-12
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);
}
}
}