Implementation principle of HashMap in JDK8

Keywords: Java

;

In JDK8

The implementation of hashMap in JDK8 adopts the mode of bucket + linked list + red black tree. When the length of linked list exceeds the threshold (the default threshold is 8), the linked list will turn to red black tree, so the design will reduce the search time.

In JDK1.6, JDK1.7

HashMap is implemented by bitbucket + linked list, that is, it uses linked list to handle conflicts, and the linked lists with the same hash value are stored in a linked list. However, when there are many elements in a bucket, that is, there are many elements with equal hash value, the efficiency of searching by key value in turn is low.

Implementation principle of hashMap (steps)

First of all, there is an array in which each element is a linked list (possibly inaccurate expression). When an element (key value) is added, the hash value of the element key is calculated first to determine the position of inserting into the array. However, the elements with the same hash value may have been placed in the same position of several groups. Then they are added after the elements with the same hash value. They are in the same position of the array The hash value of the same linked list is the same, so the array stores the linked list. When the length of the list is too long, the list will be converted into a red black tree, which greatly improves the efficiency of searching.
When the capacity of the linked list array exceeds 0.75 of the initial capacity, hash will expand the linked list array by 2 times, and move the original linked list array to a new array.

Data structure of hashMap

1. Use bucket array

transient Node<k,v>[] table;//Array to store (bitbucket) < / K, V > 

2. The array element node < K, V > implements the Entry interface

//node is a one-way linked list, which implements the Map.Entry interface
static class Node<k,v> implements Map.Entry<k,v>{
    final int hash;
    final K key;
    V value;
    Node<k,v> next;
    //Constructor hash value key next node
    Node(){
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
    }

    public final K getKey(){
        return key;
    }
    public final K getValue(){
        return value;
    }
    public final String toString(){
        return key+ "=" +value;
    }
    public fianl int hashCode(){
        retrun Objects.hashCode(key) ^ Objects.hashCode(value);
    }
    public final V setValue(V newValue){
        V oldValue = value;
        value = newValue;
        return oldValue;
    }
    //Judge whether the two node s are equal. If the key and value are equal, return true. If not, compare them to true
    public final boolean equals(Object o){
        if(o == this)
                return true;
        if(o instanceof Map.Entry){
            Map.Entry<!--?,?--> e = (Map.Entry<!--?,?-->)o;
                if(Objects.equals(key, e.getKey()) && Objects.equals(value, e.getValue()))
                return true;
        }
        return false;
    }

3. Red black tree

//Mangrove
static final class TreeNode<k,v> extends LinkedHashMap.Entry<k,v>{
            TreeNode<k,v> parent; //Parent node
            TreeNode<k,v> left; //Left subtree
            TreeNode<k,v> right; //Right subtree
            TreeNode<k,v> prev; //needed to unlink next upon deletion
            boolean red;  //color property
            TreeNode(int hash, K key,V value, Node<k,v> next){
                super(hash, key, val, next );
            }
            //Returns the root node of the current node
            final TreeNode<k,v> root(){
                for(TreeNode<k,v> r = this, p;;){
                    if((p = r.parent) == null)
                        return r;
                    r = p;
                }
            }
}

Posted by riyaz123 on Wed, 13 May 2020 09:41:17 -0700