/** 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

Consider why expansion and initialization containers must be powers of two.

How does the underlayer make sure that you input an initialization container of length to the power of two?