The Put method in HashMap
Publicv put (K key, V value) {//when key is null, call the Putfornullkey method, save null with the table in the first position, which is why HASHMAP allows null if(Key = =NULL) returnPutfornullkey (value); //calculates the hash value of a key inthash = hash (Key.hashcode ()); ------(1) //calculates the position of the key hash value in the table array inti = indexfor (hash, table.length); ------(2) //start Iteration e from I, find the location where key is saved for(entry<k, v> e = table[i]; E! =NULL; E =e.next) {Object k; //determine if the chain has the same hash value (key is the same)//If the same exists, the value is overwritten directly, returning the old value if(E.hash = = Hash && (k = e.key) = = Key | |Key.equals (k))) {V OldValue= E.value;//old value = new valueE.value =value; E.recordaccess ( This); returnOldValue;//return old value } } //1 increase in number of modificationsmodcount++; //add key, value to the I positionaddentry (hash, key, value, I); return NULL; }
Key is null:
Privatev Putfornullkey (v value) { for(entry<k,v> e = table[0]; E! =NULL; E =e.next) {if(E.key = =NULL) {V OldValue=E.value; E.value=value; E.recordaccess ( This); returnOldValue; }} Modcount++; AddEntry (0,NULL, value, 0); return NULL; }
Gets the first element of the entry table[0], and begins the traversal based on the next property of the first element until it finds a null entry, and sets its value to the new value value.
If no key is found to be null, then call addentry (0, NULL, value, 0) as above code; Add a new entry
void addentry (intint bucketindex) { Entry<K,V> e = table[ Bucketindex]; New Entry<k,v>(hash, key, value, e); if (size++ >= threshold) Resize (2 * table.length); }
Hash method:
Static int hash (int h) { ^= (H >>>) ^ (h >>>n); return H ^ (H >>> 7) ^ (H >>> 4); }
Explanation:
As a supplement to the given hashcode, the hash function can improve the quality of the hash function. The quality of the hash is very important, because HashMap with 2 recurses as the hash length of the table, which is prone to conflict, because hashcodes in the low is not different (hashcodes that DoNot differ in lower bits). Note: The hash value of the Null key is always 0, that is, his index on table is 0. Let's use examples to help us understand the above. Adding a hashcode () that says Key object returns only three values:31, 63 and 95.31, 63 and 95 are all int, so it's 32 bits. 31=00000000000000000000000000011111 63=00000000000000000000000000111111 95=0000000000000000000000000101111 1Now the table length added to HashMap is the default value of2^4, the length of the HashMap is always 2 recurses) if we do not use the hash function, Indexfor will return the following value:31=00000000000000000000000000011111 = 1111=15 63=00000000000000000000000000111111 = 1111=15 95=000000 00000000000000000001011111 = 1111=15why is that? Because when we call the Indexfor function, it executes the&15,,63&15 and 95&15 and operations, such as 95&15 Draw the result:00000000000000000000000001011111 &00000000000000000000000000001111This means (2^N-1) is always a sequence of 1, so in any case, the final execution 0&1 of Hugin 0. The above example also explains that all 1111 of the end returns the same index, so even though we have different hashcode,entry objects, the position of index 15 in table is present. If we use the hash function, for each of the above hashcode, after the hash effect is as follows:31=00000000000000000000000000011111 = 00000000000000000000000000011110 63=00000000000000000000000000111111 =& Gt 00000000000000000000000000111100 95=00000000000000000000000001011111 = 00000000000000000000000001011010now after the new hash is used, the indexfor will return:00000000000000000000000000011110 =>1110=14 00000000000000000000000000111100 =>1100=12 00000000000000 000000000001011010 =>1010=10after the use of the hash function, the above hashcodes returns a different index, so the hash function hashmap elements in the redistribution, but also reduce the conflict and improve performance. The main purpose of the hash operation is to be visible in the hashcode of the most significant bit, so that the HASHMAP elements are evenly distributed throughout the barrel. There are two points to note: If two keys have the same hashcode, then they will be assigned to the same index on the table array if two keys do not have the same hashcode, then they may, perhaps not, be assigned to the table array On the same index.
View Code
Indexfor Method:
Static int indexfor (intint length) { return H & (Length-1); }
Explanation:
This method is somewhat interesting, the main function is to locate the bucket in the HashMap. ------------------------------------------------------- You know the bottom of the HashMap is an array, and each element in the array has a linked list. This array element is called Bucket bucket ------------------------------------------------------- First review the logic and. 0 & 0 = 0;0 & 1 = 0;1 & 0 = 0;1 & 1 = 1100,1000,10000-1) is one, 111,1111,... In this case, the first argument h is smaller than the second one, and the result is H. The first parameter h is larger than the second argument, as follows: Example: H =18,10010length-1=15-01111 So when the first argument is larger than the second one equals the first parameter % Second parameter, take remainder
View Code
AddEntry
void addentry (int hash, K key, V Value, int Bucketindex) { // entry<k at Bucketindex, v> e = Table[bucketindex]; // Place the newly created Entry into the Bucketindex index and let the new Entry points to the original Entry table[bucketindex] = new entry<k, V> (hash, key, value, E); // if (size++ >= threshold) Resize ( 2 * Table.le Ngth); }
View Code
The put process:
When we want to add a pair of key-value to a hashmap, the system first calculates the hash value of the key, and then confirms the location stored in the table based on the hash value.
If the position has no elements, it is inserted directly. Otherwise, iterate over the list of elements and compare the hash value of its key accordingly.
If the two hash values are equal and the key value is equal (E.hash = = Hash && (k = e.key) = = Key | | key.equals (k)), the value of the original node is overwritten with the value of the new entry.
If two hash values are equal but the key value is unequal, the node is inserted into the chain header of the linked list (the first saved element is placed at the end of the chain), the new element is set to Entry[0], and its next pointer points to the original object, i.e. the original object is entry[1]
For example, the first key value to a comes in, by calculating the hash of its key to get the i=0, remember to do: entry[0] = A. A moment later comes in a key value pair B, by calculating that I is also equal to 0, what now? HashMap will do this: B.next = a,entry[0] = B, if it comes in again c,i is equal to 0, then C.next = b,entry[0] = C; So we find that the i=0 place actually accesses the A,b,c three key-value pairs, They are linked by the next property, which means that the last inserted element is stored in the array.
View Code
Get operation for HashMap:
PublicV get (Object key) {if(Key = =NULL) returnGetfornullkey (); inthash =Hash (Key.hashcode ()); for(Entry<k,v> e =table[indexfor (hash, table.length)]; E!=NULL; E=e.next) {Object k; if(E.hash = = Hash && (k = e.key) = = Key | | key.equals (k)))//-------------------1---------------- returnE.value; } return NULL; }
When key is null, call Getfornullkey ()
Private V Getfornullkey () { fornull; e = e.next) { ifnull) return e.value; } return NULL ; }
When key is not NULL, the hash value is obtained based on the hash function, the value of I is obtained in more indexfor (), and the loop iterates through the linked list, and if there is a key value equal to the existing key value, its value is returned.
=======================================================================================================
JDK8 's explanation diagram:
The Put method of HashMap
=====================================================================
JDK1.8 the HashMap after a lot of optimization
JDK8 because of their own modified hash of a large number of conflicts when the red-black tree has confidence, so simple, just put the high 16 bit XOR down.
static int hash (int h) { return H ^ (h >>>); }
So even if the key is more uniform and no hash conflict, theJDK8 is slightly faster than the JDK7 is probably the reason for this.
There are hash collisions, such as two hashes that fall on the same bucket after modulo, or two different keys that have the same hash value.
JDK7 's practice is to build a linked list, and then insert the elements on top of each to perform the above judgment.
And JDK8 in the chain table length reached 8, and the number of barrels reached 64, built a red black tree, to solve the serious conflict performance problems.
Http://www.cnblogs.com/chenssy/p/3521565.html
http://blog.csdn.net/zhangerqing/article/details/8193118
Http://tech.meituan.com/java-hashmap.html
Http://calvin1978.blogcn.com/articles/hashmap.html
Http://www.importnew.com/7099.html
HashMap Put,get operation