正文
HashMap.put()和get()原理
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
/**
* Returns the value to which the specified key is mapped,
* or if this map contains no mapping for the key.
*
* 获取key对应的value
*/
public V get(Object key) {
if (key == null)
return getForNullKey();
//获取key的hash值
int hash = hash(key.hashCode());
// 在“该hash值对应的链表”上查找“键值等于key”的元素
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
} /**
* Offloaded version of get() to look up null keys. Null keys map
* to index 0.
* 获取key为null的键值对,HashMap将此键值对存储到table[0]的位置
*/
private V getForNullKey() {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null)
return e.value;
}
return null;
} /**
* Returns <tt>true</tt> if this map contains a mapping for the
* specified key.
*
* HashMap是否包含key
*/
public boolean containsKey(Object key) {
return getEntry(key) != null;
} /**
* Returns the entry associated with the specified key in the
* HashMap.
* 返回键为key的键值对
*/
final Entry<K,V> getEntry(Object key) {
//先获取哈希值。如果key为null,hash = 0;这是因为key为null的键值对存储在table[0]的位置。
int hash = (key == null) ? 0 : hash(key.hashCode());
//在该哈希值对应的链表上查找键值与key相等的元素。
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
} /**
* 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.
*
* 将“key-value”添加到HashMap中,如果hashMap中包含了key,那么原来的值将会被新值取代
*/
public V put(K key, V value) {
//如果key是null,那么调用putForNullKey(),将该键值对添加到table[0]中
if (key == null)
return putForNullKey(value);
//如果key不为null,则计算key的哈希值,然后将其添加到哈希值对应的链表中
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
//如果这个key对应的键值对已经存在,就用新的value代替老的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);
return null;
}
get: 通过获取key的hashcode,然后调用 hash() 获得hash值,然后在“该hash值对应的链表”上查找“键值等于key”的元素。
put: 通过获取key的hashcode,然后调用 hash() 获得hash值,然后将其添加到哈希值对应的链表中(如果key为null,则将该键值对存储到table[0]中),如果这个key对应的键值对已经存在,就用新的value代替老的value。