學(xué)習(xí)HashMap源碼
構(gòu)造方法
//初始容量
static final int DEFAULT_INITIAL_CAPACITY = 16;
//加載因子(超過HashMap底層數(shù)組容量的加載因子倍后蓝角,擴容)
static final float DEFAULT_LOAD_FACTOR = 0.75F;
//底層數(shù)組
static final HashMap.Entry<?, ?>[] EMPTY_TABLE = new HashMap.Entry[0];
//傳入容量和加載因子
public HashMap(int var1, float var2) {
this.table = (HashMap.Entry[])EMPTY_TABLE;
this.hashSeed = 0;
this.entrySet = null;
if (var1 < 0) {
throw new IllegalArgumentException("Illegal initial capacity: " + var1);
} else {
if (var1 > 1073741824) {
var1 = 1073741824;
}
if (var2 > 0.0F && !Float.isNaN(var2)) {
this.loadFactor = var2;
this.threshold = var1;
this.init();
} else {
throw new IllegalArgumentException("Illegal load factor: " + var2);
}
}
}
//傳入容量
public HashMap(int var1) {
this(var1, 0.75F);
}
//空參數(shù)嗅定,默認容量16甜奄,加載因子0.75F
public HashMap() {
this(16, 0.75F);
}
獲取元素方法
public V get(Object var1) {
if (var1 == null) {
//hashmap的key可以是null
return this.getForNullKey();
} else {
//getEntry方法,是從數(shù)組中取hash值為索引的Entry對象
HashMap.Entry var2 = this.getEntry(var1);
return null == var2 ? null : var2.getValue();
}
}
添加元素方法
//添加方法厨内,內(nèi)部也是判斷數(shù)組是否超容膳汪,如果沒有,則將值放入數(shù) 組访雪,超容的話详瑞,增大數(shù)組容量再賦值
public V put(K var1, V var2) {
if (this.table == EMPTY_TABLE) {
//初始化
this.inflateTable(this.threshold);
}
if (var1 == null) {
return this.putForNullKey(var2);
} else {
//計算Hash值
int var3 = this.hash(var1);
//查找var1在表的位置
int var4 = indexFor(var3, this.table.length);
for(HashMap.Entry var5 = this.table[var4]; var5 != null; var5 = var5.next) {
if (var5.hash == var3) {
Object var6 = var5.key;
if (var5.key == var1 || var1.equals(var6)) {
Object var7 = var5.value;
var5.value = var2;
var5.recordAccess(this);
return var7;
}
}
}
++this.modCount;
//增加Entry 沒有找到Key
this.addEntry(var3, var1, var2, var4);
return null;
}
}
//初始化HashMap
private void inflateTable(int toSize) {
//計算出大于toSize最臨近的2的N此方的值
//假設(shè)此處傳入6, 那么最臨近的值為2的3次方,也就是8
int capacity = roundUpToPowerOf2(toSize);
//由此處可知:threshold = capacity * loadFactor
threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
//創(chuàng)建Entry數(shù)組臣缀,這個Entry數(shù)組就是HashMap所謂的容器
table = new Entry[capacity];
initHashSeedAsNeeded(capacity);
}
總結(jié)
HashMap只允許一個為null的key坝橡。
HashMap默認容量:16;它的擴容:當前table數(shù)組的兩倍
HashMap實際能存儲的元素個數(shù): capacity * loadFactor
HashMap在擴容的時候精置,會重新計算hash值计寇,并對hash的位置進行重新排列, 因此,為了效率番宁,盡量給HashMap指定合適的容量元莫,避免多次擴容