HashMap Source Code Analysis

Source: Internet
Author: User

HashMap is a non-synchronous implementation of map interface based on hash table

This implementation provides all the optional mapping operations and allows NULL values and NULL keys to be used

Hashtable and HashMap are very similar, the only difference is that the method in Hashtalbe is thread-safe, that is, synchronous

1 HASHMAP data structure:

In the Java programming language, the most basic structure is two, one is an array, the other is an analog pointer (reference),

All the data structures can be constructed with these two basic structures, and HashMap is no exception.

HashMap is actually a data structure of a "list of linked lists," where each element holds an array of chain header nodes, the combination of arrays and linked lists

As you can see, the bottom of the HashMap is an array structure, and each item in the array is a linked list

When a new HashMap is created, an array is initialized.

In the code, the name of this array is table, which is an array of type entry

Entry is the inner class of HashMap, which has the key and value properties, and a reference to the entry class next, which points to the next node

The source code is as follows:

1 transiententry[] table;2 3 4 Static classEntry<k,v>ImplementsMap.entry<k,v> {5     FinalK key;6 V value;7Entry<k,v>Next;8     Final intHash;9 ...Ten}

2 put an element into a hashmap
1  Publicv put (K key, V value) {2     //The hashmap allows null keys and null values to be stored. 3     //when key is null, the Putfornullkey method is called, and value is placed in the first position of the array. 4     if(Key = =NULL)5         returnPutfornullkey (value);6 7     //The hash value is recalculated based on the hashcode of the key. 8     inthash =Hash (Key.hashcode ());9     //searches for the index in the table that corresponds to the specified hash value. Ten inti =indexfor (hash, table.length); One  A //if the Entry at the I index is not NULL, iterate through the list continuously through the loop -      for(entry<k,v> e = table[i]; E! =NULL; E =e.next) { - Object K; the         //= = Compare if key is an object -         //compare content with key equal -         if(E.hash = = Hash && (k = e.key) = = Key | |Key.equals (k))) { -             //Replace and return the old value +V OldValue =E.value; -E.value =value; +E.recordaccess ( This); A             returnOldValue; at         } - } -  -     //If the entry at the I index is null, there is no entry here.  -     //Modcount record the number of times the structure was modified in HashMap -modcount++; in     //adds the key, value, to the I index. AddEntry (hash, key, value, I); -     return NULL; to}

1 /**2 when key is null, it is placed in the index=0 position of the table and then traverses the linked list3  */4     Privatev Putfornullkey (v value) {5          for(entry<k,v> e = table[0]; E! =NULL; E = e.next) {//null corresponding value already exists substitution occurred6             if(E.key = =NULL) {7V OldValue =E.value;8E.value =value;9E.recordaccess ( This);Ten                 returnOldValue; One             } A         } -  -     //insert null and its corresponding value for the first time the        //the corresponding storage location is table[0] -modcount++; -AddEntry (0,NULL, value, 0); -         return NULL; +}

As can be seen from the source code above: When we put the element in the HashMap, we first recalculate the hash value according to the key's hashcode, according to the hash is worth the position of the element in the array (that is, subscript), if the array is already stored in the position of other elements, Then the elements in this position will be stored in the form of a linked list, the newly added ones placed in the chain head, the first to join in the end of the chain. If the array has no elements at that position, the element is placed directly at that position in the array.

The AddEntry (hash, key, value, I) method places the Key-value pair at the I index of the array table, based on the calculated hash value. AddEntry is a way for HashMap to provide a package access (that is, there is no public,protected,private to these three access modifiers, which are the default access rights, But the code does not have this default), the code is as follows:

1 voidAddEntry (intHash, K key, V value,intBucketindex) {2     //gets the Entry at the specified Bucketindex index3Entry<k,v> e =Table[bucketindex];4     //Place the newly created Entry into the Bucketindex index and let the new Entry point to the original Entry5Table[bucketindex] =NewEntry<k,v>(hash, key, value, e);6     //if the number of key-value pairs in the Map exceeds the limit7     if(size++ >=threshold)8     //extends the length of the table object to twice times the original. 9Resize (2 *table.length);Ten}

When the system decides to store the Key-value pair in the HashMap, it does not take into account the value in entry, but only calculates and determines the storage location of each entry based on key.

We can take the value of the Map collection as a subsidiary of the key, and when the system determines where the key is stored, value is stored there.

The hash (int h) method recalculates the hash once based on the hashcode of the key. This algorithm joins the high-level calculation to prevent the low-level and high-level changes, resulting in hash collisions.

1 Static int hash (int  h) {2     H ^= (H >>>) ^ (h >>>N); 3     return H ^ (H >>> 7) ^ (H >>> 4); 4 }

We can see that in the HashMap to find an element, we need to base the hash value of the key to obtain the position in the corresponding array. How to calculate this position is the hash algorithm. Previously said HASHMAP data structure is the combination of arrays and linked lists, so we certainly hope that the hashmap inside the element location as far as possible, so that the number of elements in each position is only one, then when we use the hash algorithm to obtain this position, It is immediately possible to know that the corresponding position element is what we want, without having to traverse the linked list, which greatly optimizes the efficiency of the query.

For any given object, the hash code value computed by the program call hash (int h) method is always the same as long as its hashcode () return value is the same. The first thing we think about is the hash value of the array length modulo operation, so that the distribution of elements is relatively uniform. However, the consumption of the modulo operation is still relatively large, as is done in HashMap: Call the indexfor (int h, int length) method to evaluate which index of the table array the object should be stored in. The code for the indexfor (int h, int length) method is as follows:

Static int indexfor (intint  length) {    return H & (Length-1);}

This code guarantees that the capacity of HashMap at initialization is always 2 of the N-square, that is, the length of the underlying array is always 2 of the n-th.

When the length is always 2 of the N-time,h& (length-1) operation is equivalent to the length of the modulo, that is, H%length, but the & ratio% has a higher efficiency.

This guarantees that only two values of the same hash value will be placed in the same position in the array to form the linked list.

And when the array length is 2 of the power of n times, the different key is the same as the probability of the same index is smaller, then the data in the array distribution on the more uniform, that is, the probability of collision is small, relative, when the query does not have to traverse a position of the linked list, so query efficiency is higher.

Summary:

According to the source code of the Put method above, when the program tries to put a key-value pair into HashMap, the program first determines the storage location of the Entry based on the hashcode () return value of the key: if the Entry () of two hashcode keys The return values are the same, and they are stored in the same location. If these two Entry keys return true by equals, the newly added Entry value overrides the Entry value in the collection, but the key is not overwritten. If these two Entry keys return false by Equals, the newly added Entry will form a Entry chain with Entry in the collection, and the newly added Entry is located in the head of the Entry chain--Specify to continue to see AddEntry () Description of the method.

3 get from HashMap
1  PublicV get (Object key) {2     //key is null3     if(Key = =NULL)4         returnGetfornullkey ();5 6     //calculate subscript and traverse linked list7     inthash =Hash (Key.hashcode ());8      for(entry<k,v> e = table[indexfor (hash, table.length)]; E! =NULL; e =e.next) {9Object K;//Compare the contents of a keyTen         if(E.hash = = Hash && (k = e.key) = = Key | |Key.equals (k))) One             returnE.value; A     } -     return NULL; -}

With the hash algorithm stored above as the basis, it is easy to understand this code.

From the source code above, you can see:

When you get an element from HashMap, first calculate the hashcode of the key and find an element in the corresponding position in the array.

The required element is then found in the linked list of the corresponding position through the Equals method of key.

4 Induction

HashMap at the bottom of the key-value as a whole to deal with, this whole is a Entry object.

The HashMap bottom uses a entry[] array to hold all key-value pairs,

When a Entry object needs to be stored, the hash algorithm is used to determine where it is stored in the array, and where it is stored in the linked list on the array location according to the Equals method;

When a entry is needed, it will also find its place in the array according to the hash algorithm, and then remove the entry from the linked list at that location according to the Equals method.

HashMap Source Code Analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.