源码解析:
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
* value is replaced.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
* (A <tt>null</tt> return can also indicate that the map
* previously associated <tt>null</tt> with <tt>key</tt>.)
*/
public V put(K key, V value) {
// 若hashmap数组为空说明未初始化,是第一次往里面put值,所以先给它初始化
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
// key为null
if (key == null)
return putForNullKey(value);
// 获取key的hash值并做高位运算
int hash = hash(key);
// 根据hash高位运算得到的结果再与数组长度取模(优化之后变成h & (length-1))得到key-value键值对将要放在数组上的位置
int i = indexFor(hash, table.length);
// 遍历数组这个位置上的链表
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
// 已有相同key存在则返回与key关联的原有value值
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);
// 否则返回null
return null;
}
/**
* Offloaded version of put for null keys
*/
private V putForNullKey(V value) {
// 直接取数组第一个位置
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
// key为null,说明已有key为null的key-value存在
if (e.key == null) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
// 返回原来与值为null的key关联的value
return oldValue;
}
}
modCount++;
addEntry(0, null, value, 0);
// 否则直接返回null
return null;
}
结果验证:
@Test
public void test(){
Map<String, String>map = new HashMap<String, String>();
System.out.println(map.put(null, "a"));
System.out.println(map.put(null, "b"));
System.out.println(map.put("1", "1"));
System.out.println(map.put("1", "2"));
System.out.println(map.put("2", "2"));
System.out.println(map.put("2", "3"));
}
输出:
null
a
null
1
null
2