创建HashMap,对初始容量和负载因子进行校验
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
//如果hash表为空,则进行扩容
inflateTable(threshold);
}
if (key == null)
//如果key为null,则添加元素
return putForNullKey(value);
int hash = hash(key);
//获取key的hash值
int i = indexFor(hash, table.length);
//根据key的hash值和hash表的长度判断应该存在哪个下标
//判断是否存在相同的key,如果存在相同的key,则用后面的key对应的value替换旧的value
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
//添加链表值
addEntry(hash, key, value, i);
return null;
}
//创建一个容量大小为16的table
private void inflateTable(int toSize) {
// Find a power of 2 >= toSize
int capacity = roundUpToPowerOf2(toSize);
threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
table = new Entry[capacity];
initHashSeedAsNeeded(capacity);
}
//添加key为null的,把key为null的key-value存在table
private V putForNullKey(V value) {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(0, null, value, 0);
return null;
}
//添加链表,把新添加的值放到table第一个位置,后面的节点指向原来的。
void createEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
size++;
}