格式为put(K key, V value):
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict)代码如下:
其中final方法可修饰属性,方法,类型,表示属性不可变,方法不可重写,类型不可继承。
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
Node<K,V>[] tab;
Node<K,V> p; int n, i;
//若tab未初始化或长度为0,对其进行初始化,长度默认为16,用到了resize方法,若长度不足,容量扩大至2倍
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
//通过(n - 1) & hash确定存放在哪一个桶中,若为空,则直接写入
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {// 桶中已有元素进行判断
Node<K,V> e; K k;
//若hash值和key相同,直接覆盖
if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)//若为树节点,则为红黑树
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);//放入树中
else {//若为链表
for (int binCount = 0; ; ++binCount) {//在尾部插入新的节点
if ((e = p.next) == null) {//到达尾部
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st若链表长度超过8或整个节点超过64个,转化成红黑树
treeifyBin(tab, hash);
break;
}
//判断hash和key是否相等,相等则返回
if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;//未到尾部,继续向后传递
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)//若不唯一或旧值为空,用新值覆盖旧值
e.value = value;
afterNodeAccess(e);//返回后回调
return oldValue;//返回旧值
}
}
++modCount;//数+1
if (++size > threshold)//判断是否需要扩容
resize();
afterNodeInsertion(evict);//插入后回调
return null;
}