/** int hash: hash value calculated based on key k key: key V value:value */
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
// Check whether the global table is empty
if ((tab = table) == null || (n = tab.length) == 0)
// If the global table is empty, the initialization container is entered. The default initialization container is 16. The load factor is 0.75F
n = (tab = resize()).length;
// Compute the index of the array based on the hash value of (n-1) & if p=table is defined [calculated index]=null
if ((p = tab[i = (n - 1) & hash]) == null)
// Assign directly to the array subscript
tab[i] = newNode(hash, key, value, null);
// If there is a value in the array subscript that is not null, else logic is used
/** Node
p */
,v>
else {
Node<K,V> e; K k;
// Calculate whether the hash and key of the value in the array coordinates are the same as those of the new value and hash
if(p.hash == hash && ((k = p.key) == key || (key ! =null && key.equals(k))))
// Assign the old value of the array coordinates to e if they are the same
// e is the newly inserted value and p is the value in the array coordinates because the array coordinates are the same hash
// Now e is equal to the previous value p
/** p: Node
=YAO,YAOXIANG,NULL Node
= YAOXIANG11,NULL So the current e is the old value and now I'm going to go to step 3 **/
,v,next>
,v,next>
e = p;
// If the key is different, use the following logic
// now p is the index obtained based on the new key
/** instanceof: is a binary operator in Java, with objects on the left and classes on the right; Trur is returned if the object is created by the right-hand class or subclass, otherwise false instanceof example: public class Code { public static void main(String[] args) { Node
node = new Node<>(1, 2, new Node<>(1, 2, null, 2), 1); if( node instanceof Node){ System.out.println(true); } } static class Node
{ private int key; private T value; private Node
next; private int hash; public Node(int key,T value,Node
next,int hash){ this.key=key; this.value=value; this.next=next; this.hash=hash; }}} * /
// If the Node is a red-black tree, go to the bottom
else if (p instanceof TreeNode)
// If p at the coordinates is a red-black tree node, use the logic here
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
// If p is not a red-black tree and is a list, go through the list logically through the for loop
for (int binCount = 0; ; ++binCount) {
If next is null, add it to the last node
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
Static final int TREEIFY_THRESHOLD = 8; static final int TREEIFY_THRESHOLD = 8;
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
// Tree the entire table and the hash value red-black
treeifyBin(tab, hash);
break;
}
// If the keys are the same, overwrite and return the old value. See step 3
if(e.hash == hash && ((k = e.key) == key || (key ! =null && key.equals(k))))
break; p = e; }}// step 3 e is not null now
if(e ! =null) { // existing mapping for key
// Record the old value returned
/** So hashmap.put () returns the old value */ when hashes clash and the keys are the same
V oldValue = e.value;
if(! onlyIfAbsent || oldValue ==null)
// Replace the value of the old value with the value of the inserted value
e.value = value;
afterNodeAccess(e);
// Return the value of the old address
return oldValue;
}
}
++modCount;
Size ++ is added whenever size> threshold (load factor 0.75F * container capacity (default 16)=12)
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
Copy the code