HashMap and Concurrenthashmap differences, hashmap of the underlying source code.

Source: Internet
Author: User

The HashMap essence is an array-linked list. The hash value is obtained according to Key, and then the array subscript is computed, and if multiple keys correspond to the same subscript, the linked list is used to string up the new inserted in front.

Concurrenthashmap: On the basis of HashMap, Concurrenthashmap divides the data into multiple segment, the default 16 (concurrency level), and then each operation on a segment lock, Avoid the chance of multi-line lock and improve the concurrency efficiency.

I. Overview of HASHMAP

HashMap the implementation of the Map interface based on the hash table. This implementation provides all the optional mapping operations and allows null values and null keys to be used. (in addition to not synchronizing and allowing Nulls, theHashMap class is roughly the same as Hashtable .) This class does not guarantee the order of the mappings, especially because it does not guarantee that the order is constant.

It is important to note that HashMap is not thread-safe, and if you want thread-safe hashmap, you can synchronizedmap get thread-safe HashMap through the static method of the Collections class.

1  Map map = Collections.synchronizedmap (new HashMap ());

II. data structure of HashMap

 The bottom of the HashMap is mainly based on arrays and linked lists, and it has a fairly fast query speed because it determines the location of the store by calculating the hash code, and can quickly calculate where the object is stored. HashMap is mainly through the key hashcode to calculate the hash value, as long as hashcode the same, the calculated hash value is the same. If you store more objects, it is possible that different objects will have the same hash value, and there is the so-called hash conflict. The students who have learned the data structure know that there are many ways to solve the hash conflict, hashmap the bottom is to solve the hash conflict through the list.

                                      

As can be seen, HashMap is an array structure, the array is stored in a entry object, if the resulting hash conflict, that is to store the location above already stored objects, at this time the location is a linked list. Let's look at the code for the entry class in HashMap:

1 Static class Entry<k,v> implements Map.entry<k,v> {2         final K key; 3         V value; 4         entry<k,v> Next  5         final int hash; 6  7         /** 8          * Creates new entry. 9          */10         entry (int h, K K, v V, entry<k,v> N) {One             value = v;12             next = n;//hash value after the conflict is stored in the list of the next             key = k;14             hash = h;15         }16         ... (+     }

HashMap is actually a entry array, entry object contains the key and the value, where next is also a entry object, it is used to deal with the hash conflict, form a linked list.

Third, HashMap source analysis

  First look at some of the key properties in the HashMap class:

1 transient entry[] table;//The entity array that stores the Elements 2 3 transient int size;//The number of elements stored 4 5 int threshold; Threshold value expands   when the actual size exceeds the critical value threshold = load factor * Capacity 6 7 final float loadfactor;//load factor 8 9 transient int modcount;//number of changes

The loading factor is the degree to which the elements in the hash table are filled. If: the larger the load factor, the more elements filled, the advantage is that space utilization is high, but the chances of conflict are increased. Conversely, the smaller the load factor, the less elements that fill,
The advantage is that the chances of conflict are reduced, but the space is wasted. The greater the chance of conflict, the higher the cost of finding it. Conversely, the lower the cost of finding. Thus, the smaller the lookup time. Therefore, it is necessary to find a balance and compromise between "conflict of opportunity" and "space utilization". This balance and tradeoff is essentially a balance and tradeoff between the well-known "time-space" contradictions in the data structure.

If the machine memory is sufficient and you want to increase the query speed, you can set the load factor to a smaller point, but if the machine memory is tight and there is no requirement for the query speed, you can set the load factor a bit larger. But generally we do not have to set it, let it take the default value of 0.75 is good.

Here's a look at some of the construction methods of HashMap:

 1 public HashMap (int initialcapacity, float loadfactor) {2//ensure digital legitimacy 3 if (initialcapacity < 0) 4                                                throw new IllegalArgumentException ("Illegal initial capacity:" + 5 initialcapacity); 6 if (initialcapacity > maximum_capacity) 7 initialcapacity = maximum_capacity; 8 if (loadfactor <= 0 | |                                                Float.isnan (Loadfactor)) 9 throw new IllegalArgumentException ("Illegal load factor:" +10 Loadfactor)//Find a power of 2 >= initialCapacity13 int capacity = 1   ; Initial capacity (capacity < initialcapacity)//Ensure a capacity of 2 n power, so that capacity is greater than initialcapacity of the smallest 2 of the N power of C         Apacity <<= 1;16 this.loadfactor = loadfactor;18 threshold = (int) (capacity * loadfactor); 19 Table = new ENTRY[CAPACITY];20 init ()}22 HashMap (int initialcapacity) {24 This (initialcapacity, default_load_factor),}26 HashMap () {this.loadfactor = DEFA ult_load_factor;29 threshold = (int) (default_initial_capacity * default_load_factor), table = new entry[ DEFAULT_INITIAL_CAPACITY];31 init (); 32}

We can see that when we construct the HashMap, we call the first constructor if we specify the loading factor and the initial capacity, otherwise the default is the one. The default initial capacity is 16, and the default load factor is 0.75. We can see the above code in 13-15 lines, the function of this code is to ensure that the capacity of the N power of 2, so that the capacity is greater than initialcapacity the smallest 2 of the power of N, as to why the capacity is set to 2 of the N power, we wait to see.

Here's a look at how the HashMap stores the data, first look at the HashMap put method:

 1 public V put (K key, V value) {2 if (key = = NULL)//If the key is null, call Putfornullkey (value) 3 return Putfornullkey (value); 4 int hash = hash (Key.hashcode ());//hash code 5 int i = indexfor (hash, table.length) according to the key hashcode; 6 for (entry<k,v> e = table[i]; e = null; e = e.next) {//handle conflict, if hash value is the same, store 7 Object K in that location with the list ;  8 if (E.hash = = Hash && (k = e.key) = = Key | | key.equals (k)) {//If key is the same, overwrite and return old value 9 V OldValue = e.value;10 E.value = value;11 e.recordaccess (this), return O ldvalue;13}14}15 modcount++;17 addentry (hash, key, value, I); return nu LL;19} 

When we put the element in the HashMap, it is worthwhile to place the element in the array (i.e. subscript) according to the hash of the key, and then we can put the element in the corresponding position. If there are other elements in the seat of this element, then the elements in the same seat will be stored in the form of a list, and the newly added ones are placed in the chain head, and the first ones are placed at the end of the chain. When a get element is obtained from HashMap, the hashcode of the key is computed first, an element in the corresponding position in the array is found, and the required element is found in the linked list of the corresponding position through the Equals method of key.

The specific implementation is:

When your key is null, Putfornullkey,hashmap is called to allow key to be null, such that the pair is placed in table[0].

If not null, the int hash = hash (Key.hashcode ()) is called; this is a custom hash of HashMap, two hashes on the basis of Key.hashcode ()

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

After the hash code is obtained, the hash code is computed to calculate the index that should be stored in the array, and the function of the index is as follows:

1 static int indexfor (int h, int length) {  2        return H & (length-1);  3    }  

This method is very ingenious, it through H & (table.length-1) to get the object's save bit, and hashmap the length of the underlying array is always 2 of the N-square, which is hashmap on the speed of optimization. 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. 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 is 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.

Now we go back to the put method, we have computed the value of the index, and we see the 6th to 14th line, if the list of the index in the array already has an object of the same key, overwrite it and return the original value. If there is no key that is the same as key, the AddEntry method is called to create a entry object, and the AddEntry method is as follows:

1 void addentry (int hash, K key, V value, int bucketindex) {2         entry<k,v> e = Table[bucketindex];//If the position to be joined has a value, the The original value of the position is set to the next of the new Entry, which is the next node of the new Entry List 3         table[bucketindex] = new entry<> (hash, key, value, e); 4         if ( size++ >= threshold)//If the threshold value is greater than 5             resize (2 * table.length);//2 in multiples of the expansion of 6     }

The parameter bucketindex is the index value computed by the Indexfor function, the 2nd line of code is to get the entry object indexed to Bucketindex in the array, and the 3rd line is hash, key, Value constructs a new entry object where the index is Bucketindex, and sets the original object of that location to the next constituent list of the new object.

Line 4th and 5th is to determine whether the size of the put to reach the critical value threshold, if the threshold is reached to expand, hashmap expansion is twice times the original. The resize () method is as follows:

1 void Resize (int newcapacity) {2         entry[] oldtable = table; 3         int oldcapacity = oldtable.length; 4         if (oldcap  Acity = = maximum_capacity) {5             threshold = Integer.max_value; 6             return; 7         } 8  9         entry[] newtable = new ENTRY[NEWCAPACITY];10         Transfer (newtable);//used to move all the elements of the original table into the newtable         table = newtable;  Assign newtable to table12         threshold = (int) (newcapacity * loadfactor);//recalculate critical value     

Expansion is required for array replication, the above code in the 10th Act copy array, copy array is very performance-consuming operation, so if we have predicted the number of elements in HashMap, then the number of preset elements can effectively improve the performance of HashMap.

HashMap and Concurrenthashmap differences, hashmap of the underlying source code.

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.