The hash list, the API implementation in the JDK is the HashMap class.
Why is hashmap called "Hash list"? This is related to the internal storage structure of HashMap. The following will be analyzed according to the source code.
The first thing to say is that an array is maintained in HashMap: transient node<k,v>[] table , and each element in the array is a Node object. Node here is an inner class of HashMap, with the following code:
Static classNode<k,v>ImplementsMap.entry<k,v> { Final intHash; FinalK Key; V value; Node<K,V>Next; Node (intHash, K key, V value, node<k,v>next) { This. hash =Hash; This. Key =key; This. Value =value; This. Next =Next; } Public FinalK GetKey () {returnkey;} Public FinalV GetValue () {returnvalue;} Public FinalString toString () {returnKey + "=" +value;} Public Final inthashcode () {returnObjects.hashcode (key) ^Objects.hashcode (value); } Public Finalv SetValue (v newvalue) {v OldValue=value; Value=NewValue; returnOldValue; } Public Final Booleanequals (Object o) {if(O = = This) return true; if(Oinstanceofmap.entry) {map.entry<?,? > E = (map.entry<?,? >) O; if(Objects.equals (Key, E.getkey ()) &&objects.equals (value, E.getvalue ()))return true; } return false; }}
As you can see, this node class is clearly the structure of a linked list. In other words, HashMap is an array of linked lists, so that HashMap as a "linked list" part is clear.
So why is HashMap also defined as "hash"? Let's look at the put () method in HashMap. The Putval ( ) method is called directly in the put () method, and the Putval () method code is as follows:
FinalV Putval (intHash, K key, V value,BooleanOnlyifabsent,Booleanevict) {Node<k,v>[] tab; Node<k,v> p;intN, I; if(tab = table) = =NULL|| (n = tab.length) = = 0) n= (Tab =resize ()). length; if(p = tab[i = (n-1) & hash]) = =NULL) Tab[i]= NewNode (hash, key, value,NULL); Else{Node<K,V>e; K K; if(P.hash = = Hash &&((k= p.key) = = Key | | (Key! =NULL&&Key.equals (k)))) E=p; Else if(pinstanceofTreeNode) e= ((treenode<k,v>) p). Puttreeval ( This, tab, hash, key, value); Else { for(intBincount = 0;; ++Bincount) { if((e = p.next) = =NULL) {P.next= NewNode (hash, key, value,NULL); if(Bincount >= treeify_threshold-1)//-1 for 1sttreeifybin (tab, hash); Break; } if(E.hash = = Hash &&((k= e.key) = = Key | | (Key! =NULL&&Key.equals (k)))) Break; P=e; } } if(E! =NULL) {//existing mapping for keyV OldValue =E.value; if(!onlyifabsent | | oldValue = =NULL) E.value=value; Afternodeaccess (e); returnOldValue; } } ++Modcount; if(++size >threshold) resize (); Afternodeinsertion (evict); return NULL;}
As you can see from the code above, the HashMap analyzes which chain the node should be stored in by using the hash () method in the HashMap to obtain the hashing code of the key of the current element, and then pass (n-1) & Hash operation to determine which chain the node should be on. In this way, it is equivalent to creating an "index" in the HashMap, if you want to take the element, only through the hash value of key, you can easily index to the node's chain, thus traversing all the elements in the chain, finally get the target node, greatly improve the efficiency of the lookup. In this way, some subscripts in the array may not store any data, and the HashMap "hash" is shown here.
HashMap's idea of "hashing" makes HashMap's query more efficient than any other data structure. However, as we all know, the best hash is that each element in the array is a chain of only one node, that is, each subscript in the array corresponds to only one node, so that the HashMap query efficiency can be guaranteed to reach the highest. Of course, this situation is difficult to achieve, but HashMap provides us with a mechanism that can achieve this effect to a great extent, that is, the HashMap expansion mechanism.
The HashMap expansion mechanism is embodied in the Putval () method: if (++size > Threshold) resize (); . Resize () method is HashMap expansion method, detailed later, threshold is the hashmap of the expansion threshold value, the default is the current HashMap in the length of the array 0.75 times times; size is the number of nodes that are stored in the current HASHMAP. In other words, when the number of nodes stored in the HashMap exceeds the threshold for expansion, it is time to start expanding. In this way, the HashMap is able to maximize the best hash effect. Simply put, if you do not expand, then all elements will be squeezed in that array, it will inevitably lead to an array of one subscript corresponding to the chain is too long, and through the expansion of (n-1) & Hash operation of the cardinality n, so the elements can be re-hash, spread more scattered. HashMap is the way to achieve hashing.
Hash list of "Data structure" (Java language description)