Lead
HashMap is a common data structure, understanding the HashMap, to improve the efficiency of the code is a great help. HashMap optimizes the data structure in JDK1.8: It improves the efficiency of query and deletion . Of course, this also leads to a more complex structure, but through the careful reading of the source, still can grasp its essentials.
After reading this post, you should understand the content
Click here to view larger image
Description: The data structure of HASHMAP is a hash table (which can be understood as an array), with some nodes stored in each slot.
- In general, a slot is stored in a node;
- When the amount of data is large, a slot may hold multiple nodes, at which point the nodes are connected together in the form of a linked list;
- When the number of nodes in a slot is large (more than 8), these nodes are saved in a red-black tree
Source Understanding
member Variables
//array default sizeStatic Final intDefault_initial_capacity =1<<4;//AKA//The maximum capacity of the arrayStatic Final intMaximum_capacity =1<< -;//Load factorStatic Final floatDefault_load_factor =0.75F//Threshold: When the number of nodes in the slot increases gradually, when the value is exceeded, the node is converted from the form of the list to the form of a red-black treeStatic Final intTreeify_threshold =8;//Threshold: When the number of nodes in a slot gradually decreases, the node is converted from the red-black tree to the form of a linked list when the value is exceeded .Static Final intUntreeify_threshold =6;//red-black tree minimum capacityStatic Final intMin_treeify_capacity = -;//arrays, containers that are really used to hold datatransientNode<k,v>[] table;//For traversal, this article does not introducetransientSet<map.entry<k,v>> EntrySet;//Sizetransient intSize//Number of changestransient intModcount;//Threshold: When the number of data in an array is greater than this value, the array expandsintThreshold//Load factorFinal floatLoadfactor;
Note: As can be seen from table, HashMap is the most basic data structure is the number of groups, the rest of the member variables alone analysis is not what results, need to combine the following content to understand. Starting with the commonly used put (), get (), remove () begins to understand.
Construction Method
Before this, of course, we should see how it is constructed:
Public HashMap() {//Load factor is the default value This. loadfactor = Default_load_factor;//The array is not initialized here}//Custom initialcapacity, load factor with default value Public HashMap(intinitialcapacity) { This(Initialcapacity, default_load_factor);}//Custom initialcapacity, and Loadfactor Public HashMap(intInitialcapacity,floatLoadfactor) {//verification of some illegal parameters if(Initialcapacity <0)Throw NewIllegalArgumentException ("Illegal initial capacity:"+ initialcapacity);if(Initialcapacity > maximum_capacity) initialcapacity = maximum_capacity;if(Loadfactor <=0|| Float.isnan (Loadfactor))Throw NewIllegalArgumentException ("Illegal load factor:"+ Loadfactor);//Set load factor This. loadfactor = Loadfactor;//Set the threshold value, the threshold size of 2 ///For example: Initialcapacity = 17 with a threshold value of //initialcapacity = 5 with a threshold of 8 //initialcapacity = 55, threshold value is This. Threshold = Tablesizefor (initialcapacity);} Public HashMap(map<? extends K,? extends v> m) {//Load factor is the default value This. loadfactor = Default_load_factor;//The data in M is stored in the current mapPutmapentries (M,false);}
Description: The first three construction methods, just initialize some parameters, not too many operations, the fourth construction method is more complex, this post read, then go to see the source code is easy to understand, there is no discussion.
put () method
//Indirect key-value pairs PublicVput(K key, Vvalue) {returnPutval (hash (key), Key,value,false,true);} Final V Putval (intHash, K key, Vvalue, Boolean onlyifabsent, Boolean evict) {//tab--array, the container used to hold the data //P-The first node in the corresponding array slot //N--size of the array //I--the position where the current key-value pair should be stored in the arraynode<k,v>[] tab; Node<k,v> p;intn, I;//processing of data added for the first time if(tab = table) = =NULL|| (n = tab.length) = =0)//array size using default valuesn = (tab = resize ()). length;no processing of nodes in the corresponding slots if(p = Tab[i = (N-1) (& hash]) = =NULL)//Add a new nodeTab[i] = NewNode (hash, key,value,NULL);//processing of nodes in corresponding slots Else{//e--used to mark nodes that meet the criteria //k--keyNode<k,v> e; K K;the first node in//slot meets the required processing if(P.hash = = Hash && (k = p.key) = = Key | | (Key! =NULL&& Key.equals (k)))) E = p;//Slot data structure for red-black tree processing Else if(P instanceof TreeNode)//will try to find the appropriate node from the tree and update //If not found, create a new node and add it to the treeE = ((treenode<k,v>) p). Puttreeval ( This, tab, hash, key,value);//Slot data structure for chain list processing Else{//Traverse the list to find the corresponding value for(intBincount =0; ; ++bincount) {//Traverse to the end of the list and still not find the corresponding node, create a new node, encapsulate the key-value pair to that node, and add it to the tail of the list if((e = p.next) = =NULL) {P.next = NewNode (hash, key,value,NULL);//If the length of the list is greater than the threshold (8), then convert the linked list to a red-black tree if(Bincount >= Treeify_threshold-1)//-1 for 1stTreeifybin (tab, hash); Break; }//Description current E meets condition, end traversal if(E.hash = = Hash && (k = e.key) = = Key | | (Key! =NULL&& Key.equals (k)))) Break; p = e; } }//When a node meets the requirements, update the data in the node if(E! =NULL) {V OldValue = e.value;if(!onlyifabsent | | oldValue = =NULL) E.value=value;I'll use it in//linkedhashmap.Afternodeaccess (e);returnOldValue; }} ++modcount;//If the current size is greater than the threshold value, expand the size of the array if(++size > Threshold) resize ();I'll use it in//linkedhashmap.Afternodeinsertion (evict);return NULL;}
Description: The details of the implementation are tedious, but the summary is simple:
- Create a node without a corresponding node, and put it in the right place
- The corresponding node is found to update the data in the corresponding node.
Additional Instructions:
- Put () does not save repeatedly key,hashset is to use this to achieve the heavy
- Linkedhashmap will rewrite some of these methods to implement the corresponding features
get () method
//Find value by key PublicVGet(Object key) {node<k,v> E;//Find the appropriate node and return value return(E = getnode (hash (key), key) = =NULL?NULL: E.value;}//Find the corresponding nodeFinal Node<k,v> GetNode (intHash, Object key) {//tab--array //First-array corresponding slot //e--the corresponding node //N--the length of the array //K--Keynode<k,v>[] tab; Node<k,v> First, E;intN K K;if(tab = table)! =NULL&& (n = tab.length) >0&& (first = tab[(N-1) & hash])! =NULL) {//Top that picture has a reminder: In general, there is only one data in a slot, so //In general, first check whether the first node meets the requirements, comply with, directly return to the node, otherwise continue to find if(First.hash = = Hash &&//Always check first node(k = first.key) = = Key | | (Key! =NULL&& Key.equals (k))))returnFirst//The first node does not conform to the processing if((E = first.next)! =NULL) {//data structure for processing of red and black trees if(First instanceof TreeNode)return((treenode<k,v>) first). Gettreenode (hash, key);//Data structure for chain list processing Do{if(E.hash = = Hash && (k = e.key) = = Key | | (Key! =NULL&& Key.equals (k))))returnE } while((E = e.next)! =NULL); } }//did not find the corresponding node return NULL;}
Description: Get () can be divided into such a few steps:
- Locking Slots
- Find the appropriate node from the slot
- Return the appropriate data
Remove () method
//Remove the corresponding node PublicVRemove(Object key) {node<k,v> E;return(E = RemoveNode (key), Key,NULL,false,true)) ==NULL?NULL: E.value;}//Remove the corresponding nodeFinal Node<k,v> RemoveNode (intHash, object key, Objectvalue, Boolean matchvalue, Boolean movable) {//tab--array, the container used to hold the data //P--the first node in the array slot corresponding to index //N--size of the array //index--where the current key should be stored in the arraynode<k,v>[] tab; Node<k,v> p;intn, index;if(tab = table)! =NULL&& (n = tab.length) >0&& (p = Tab[index = (N-1) & hash])! =NULL) {//node--Meet the requirements of the node //E--marks the next node of the current node //K--Key //V--valuenode<k,v> node =NULLE K K; V V;//Top that picture has a reminder: In general, there is only one data in a slot, so //In general, first check whether the first node meets the requirements, comply with, directly return to the node, otherwise continue to find if(P.hash = = Hash && (k = p.key) = = Key | | (Key! =NULL&& Key.equals (k)))) node = p;//The first node does not conform to the processing Else if((E = p.next)! =NULL) {//data structure for processing of red and black trees if(P instanceof TreeNode) node = ((treenode<k,v>) p). Gettreenode (hash, key);//Data structure for chain list processing Else{ Do{if(E.hash = = Hash && (k = e.key) = = Key | | (Key! =NULL&& Key.equals (k))) {node = e; Break; } p = e; } while((E = e.next)! =NULL); } }//Determine if node meets the deletion criteria if(Node! =NULL&& (!matchvalue | | (v = node.)value) ==value|| (value!=NULL&&value. Equals (v)))) {//structure for red and black trees when the operation if(Node instanceof TreeNode) ((treenode<k,v>) node). Removetreenode ( This, tab, movable);//The node to be deleted is a linked list and is processed for the first node in the slot Else if(node = = p) Tab[index] = Node.next;//Data structure for chain list processing ElseP.next = Node.next; ++modcount; --size;I'll use it in//linkedhashmap.Afternoderemoval (node);returnNode } }return NULL;}
Description: To put it simply: Locate the appropriate node and delete and follow the rules to move the remaining nodes in the slot.
Conclusion
Then go to see the fourth construction method, is nothing more than a variable to pass in the map, the data encapsulated in HashMap.
This article does not make any further analysis on the operation of the linked list and the red-black tree. Personally, reading the source code, if too much attention to detail may be difficult to grasp the overall idea, of course, some time to see the source code needs to pay attention to the details, which requires us to balance, the source of more than a look, this sense of balance will have. (The list and the red-black tree after the operation of the article will do some separate instructions)
Finally, once again, the core, that is, the first picture to be affixed.
Click here to view larger image
Reprint please indicate the source http://blog.csdn.net/qq_26411333/article/details/51723828
HashMap Source Understanding