Java collection class-HashMap part of the source code implementation

HashMap

Both the key and value of HashMap are allowed to be null, which is not thread-safe, and there is no guarantee that the internal order of the elements will not change . The underlying data structure adopts an array + a singly linked list/red-black tree , with a bucket array as the main body of the HashMap, and a linked list or red-black tree to resolve hash conflicts.
Insert picture description here

Next, learn from the JDK source code:
The initial capacity of HashMap is 16, and the default load factor in the constructor is 0.75. When this value is reached, the array will be expanded twice .
Insert picture description here
Insert picture description here
You can also pass in the capacity and load factor parameters yourself
Insert picture description here
扩容机制:
1. First judge whether the current capacity has reached the maximum capacity, if it is reached, no further expansion.
Insert picture description here
2. If the current capacity exceeds 16 and the capacity is still less than the maximum capacity after being doubled, the capacity is doubled.
Insert picture description here
3. If it is a completely new bucket array, assign the default capacity of 16 and the default expansion threshold (16 * 0.75 = 12)
Insert picture description here
4. If the expansion threshold is 0 (newThr), the expansion is calculated based on the current capacity and load factor Threshold value.
Insert picture description here
5. Finally build a new bucket array (newTab) according to the capacity obtained above and store the original array in it.

this.threshold = newThr;
        HashMap.Node<K, V>[] newTab = new HashMap.Node[newCap];
        this.table = newTab;
        if (oldTab != null) {
    
    
            for(int j = 0; j < oldCap; ++j) {
    
    
                HashMap.Node e;
                if ((e = oldTab[j]) != null) {
    
    
                    oldTab[j] = null;
                    if (e.next == null) {
    
    
                        newTab[e.hash & newCap - 1] = e;
                    } else if (e instanceof HashMap.TreeNode) {
    
    
                        ((HashMap.TreeNode)e).split(this, newTab, j, oldCap);
                    } else {
    
    
                        HashMap.Node<K, V> loHead = null;
                        HashMap.Node<K, V> loTail = null;
                        HashMap.Node<K, V> hiHead = null;
                        HashMap.Node hiTail = null;

                        HashMap.Node next;
                        do {
    
    
                            next = e.next;
                            if ((e.hash & oldCap) == 0) {
    
    
                                if (loTail == null) {
    
    
                                    loHead = e;
                                } else {
    
    
                                    loTail.next = e;
                                }

                                loTail = e;
                            } else {
    
    
                                if (hiTail == null) {
    
    
                                    hiHead = e;
                                } else {
    
    
                                    hiTail.next = e;
                                }

                                hiTail = e;
                            }

                            e = next;
                        } while(next != null);

                        if (loTail != null) {
    
    
                            loTail.next = null;
                            newTab[j] = loHead;
                        }

                        if (hiTail != null) {
    
    
                            hiTail.next = null;
                            newTab[j + oldCap] = hiHead;
                        }
                    }
                }
            }
        }

        return newTab;

put(K key, V value):
1. Get the hash value of the incoming key.
Insert picture description here
Insert picture description here
2. Determine whether the current tab value is null or whether the length is 0. If it is, perform the expansion operation.
Insert picture description here
3. Obtain the subscript in the table from the hash value through the hash function. If there is no element in the current position, a new node is constructed and stored in the current position.
Insert picture description here
4. If the key and hash values ​​of the current node are consistent with the passed parameters, they will be overwritten.
Insert picture description here
5. If the current node location stores the red-black tree, then insert the red-black tree.
Insert picture description here
6. If the current node location stores a linked list, traverse the node in the fourth step of finding the symbol and cover it, otherwise insert the node at the end of the linked list, and judge whether it needs to be converted to a red-black tree and expansion operation.
Insert picture description here
get(Object key):

The get method is similar to the put method. The corresponding hash value is obtained through the key value, and then converted into an array subscript, and then the position data is traversed and searched.
Insert picture description here
Insert picture description here
remove(Object key):
1. Determine whether the corresponding subscript of the table and the key value passed in is empty
Insert picture description here
. 2. Determine whether the first node of the linked list is a search node
Insert picture description here
. If yes, assign it to node 3. If the current location stores a red-black tree, use it The getTreeNode method finds the node.
Insert picture description here
4. If it is a linked list, traverse to find the node and assign it to the node.
Insert picture description here
5. The node is judged to be empty, and at the same time, it is judged whether its value is equal to the incoming parameter, and then deleted.
Insert picture description here
注意: The equals method compares the memory addresses of two elements by default, so we need to overwrite the equals method to ensure that the key value will not be repeated.

Guess you like

Origin blog.csdn.net/m0_46550452/article/details/107282080