static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
static final int MAXIMUM_CAPACITY = 1 << 30;
static final float DEFAULT_LOAD_FACTOR = 0.75f;
public HashMap() {
this(DEFAULT_INITIAL_CAPACITY, 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; //最大容量为2^30
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
threshold = initialCapacity;
init();
}
hashmap的初始容量为16,最大容量为2^30。
void addEntry(int hash, K key, V value, int bucketIndex) {
//当前容量大于或等于阈值 扩容2倍
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length);
hash = (null != key) ? hash(key) : 0;
//获取新添加的值在数组中的索引
bucketIndex = indexFor(hash, table.length);
}
createEntry(hash, key, value, bucketIndex);
}
//当容量不足时(容量 > 阈值),则扩容(扩到2倍)
void resize(int newCapacity) {
Entry[] oldTable = table;
int oldCapacity = oldTable.length;
if (oldCapacity == MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return;
}
Entry[] newTable = new Entry[newCapacity];
//元素迁移
transfer(newTable, initHashSeedAsNeeded(newCapacity));
table = newTable;
//获取阈值和最大容量的最小值
threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
}
//将旧数组上的数据转移到新newTable中,从而完成扩容
void transfer(Entry[] newTable, boolean rehash) {
// 获取新数组的大小
int newCapacity = newTable.length;
//遍历 旧数组
for (Entry<K,V> e : table) {
while(null != e) {
Entry<K,V> next = e.next;
if (rehash) {
//修改key值为null的hash值
e.hash = null == e.key ? 0 : hash(e.key);
}
//重新计算每个元素的存储位置
int i = indexFor(e.hash, newCapacity);
//将元素给新数组
e.next = newTable[i];
newTable[i] = e;
e = next;
}
}
}
没添加一个新值就要判断下,如果新容量超过旧容量的0.75倍,则扩容2倍,
由源码得知:线程不安全。
因为根据hash值算出数组的位置,所以数组是没有顺序的
可以插入null键值,不能存储相同的key