1. HashMap Key points:
1.1 Basic data structure :
Using the combination of array + list/balanced binary search tree , all key-value pairs are stored in entry<k,v> form (one key-value pair per put, one entry<k, v>).
- An array of:entry<k,v> arrays, with hash (Key.hashcode ()) as an array index. That is, the hash value of the key value is computed, which is the index store key value pair entry<k, v>. The array length is always 2 of the n-th square (this is related to the hash, the back will speak)
- Linked list: If the hash () method calculates the same hash value, at that index, set up the linked list, store the hash value of the same key value pairs.
- Balanced binary search tree: If the current index is a linked list, and after inserting the current key-value pair, the number of elements in the list exceeds the threshold (8), then the linked list at the current index is converted to a balanced binary lookup tree; if it is a tree at the current index, directly insert the current key value
The definition of table in the JDK1.8 version (Node<k, v> implements the interface Entry<k,v>):
/** * The table, initialized on first use, and resized as * necessary. When allocated, the length is always a power of. * (We also tolerate length zero in some operations to allow * bootstrapping mechanics that is currently not needed.) */ transient Node<k,v>[] table; //static class Node<k,v> implements Map.entry<k,v>
Table initial value is 16, expansion, each time the original twice times. Below is the definition of the table's initial value (the word length of the basic data type in Java is fixed and the platform is independent.) such as int is always 4bytes, so the table index is the maximum value of the integer type. ):
1 /**2 * The default initial capacity-must be a power of.3 */4 Static Final intdefault_initial_capacity = 1 << 4;//aka5 6 /**7 * The maximum capacity, used if a higher value is implicitly specified8 * by either of the constructors with arguments.9 * Must be a power of <= 1<<30.Ten */ One Static Final intmaximum_capacity = 1 << 30; A - /** - * The bin count threshold for using a tree rather than list for a the * bin. Bins is converted to trees when adding an element to a - * Bin with at least this many nodes. The value must be greater - * than 2 and should is at least 8 to mesh with assumptions in - * Tree removal about conversion back to plain bins upon + * shrinkage. - */ + Static Final intTreeify_threshold = 8;the threshold value of the number of linked list elements at each index, over which the binary lookup tree is stored
1.2 Hashing algorithm
JDK1.8 version of the source code is as follows:
/** * computes Key.hashcode () and spreads (xors) higher bits of hash * to lower. Because The table uses Power-of-two masking, sets of * hashes that vary only in bits above the current mask would * Always collide. (among known examples is sets of Float keys * Holding consecutive whole numbers in small tables.) So we * apply a transform that spreads the impact of higher bits * downward. There is a tradeoff between speed, utility, and * quality of bit-spreading. Because Many common sets of hashes * is already reasonably distributed (so don ' t benefit from * spreading), and b Ecause we use trees to handle large sets of * collisions in bins, we just XOR some shifted bits in the * cheapest Possible-to-reduce systematic lossage, as well as *-incorporate impact of the highest bits that would otherwise * Never is used in index calculations because of table bounds. */ Static Final intHash (Object key) {inth; return(Key = =NULL) ? 0: (H = key.hashcode ()) ^ (H >>> 16); }
The hash value of the key value is about to Key.hashcode () a high 16-bit with a low 16-bit bitwise XOR result.
There are several points:
- Key.hashcode (): Hashcode () is the local method of the object class. The key-Value object class can override its own hashcode () method, such as the Hashcode () method of the integer class to return only its int value.
- Hash (): To avoid key.hashcode () to get the hash value repeated too much, such as the integer class is very simple, so it added a layer of hash. However, it is possible that the original Hashcode () method is already good, so after measuring the efficiency and effect, we use the simplest method to obtain the new hash value.
- H>>>16: The result of this hash value is that the high 16 bits are different from the lower 16 bits, and stored in the low 16 bits. That is, the hash value is a 16 bit bit value, which is related to the table length described in 1.1, because the table index is the hash value.
1.3 main basic operations1.3.1 put ()
- There are no key-value pairs at the index and are inserted directly into the list
- Otherwise, if there is the same key value in the tree or in the linked list, the original value value is updated and the old value value is returned
- Otherwise, if the linked list is inserted into the linked list, and the length threshold is exceeded, then the binary lookup tree is converted; If it is a tree, insert the tree
JDK1.8 version source code is as follows:
1 Publicv put (K key, V value) {2 returnPutval (hash (key), key, value,false,true);3 }4 5 /**6 * Implements Map.put and related methods7 *8 * @paramHash Hash for key9 * @paramKey The keyTen * @paramvalue the value to put One * @paramonlyifabsent If True, don ' t change existing value A * @paramevict if False, the table is in creation mode. - * @returnprevious value, or null if none - */ the FinalV Putval (intHash, K key, V value,BooleanOnlyifabsent, - Booleanevict) { -node<k,v>[] tab; Node<k,v> p;intn, I;
//If the current table is empty or 0, the table is initialized with resize (), - if(tab = table) = =NULL|| (n = tab.length) = = 0) +n = (tab =resize ()). length;
//If there is no value at the hash index of the current key value, the key value pair is stored directly at the index - if(p = tab[i = (n-1) & hash]) = =NULL) +Tab[i] = NewNode (hash, key, value,NULL);
//If there is a value at the hash index of the current key value A Else { atNode<k,v>e; K K;
//If the key value at the current index is the same as the key value to be inserted (that is, the key value pair to be inserted is the same as the key value of the first key value pair in the bin)----even if it is a different object, the value is the same (as determined by the Equals () method) - if(P.hash = = Hash && -(k = p.key) = = Key | | (Key! =NULL&&key.equals (k) ))) -E =p;
//Otherwise, if the current bin is stored as a tree node, insert the node into the tree - Else if(pinstanceofTreeNode) -E = ((treenode<k,v>) p). Puttreeval ( This, tab, hash, key, value); //If the node is already in the tree, return the value before this node, if NULL is not returned
//Otherwise, the current bin is stored as a list, traversing the linked list, inserting the node in Else { - for(intBincount = 0;; ++Bincount) { to if((e = p.next) = =NULL) { +P.next = NewNode (hash, key, value,NULL); - if(Bincount >= treeify_threshold-1)//-1 for 1st //If the number of elements exceeds the threshold after inserting a node, convert the linked list to a two-fork lookup tree the treeifybin (tab, hash); * Break; $ }Panax Notoginseng if(E.hash = = Hash && -(k = e.key) = = Key | | (Key! =NULL&&key.equals (k) ))) the Break; +p =e; A } the }
If there is a key-value pair with the same key value at the index, the value of the original key-value pair is updated to the new value, returning the old value + if(E! =NULL) {//existing mapping for key -V OldValue =E.value; $ if(!onlyifabsent | | oldValue = =NULL) $E.value =value; - afternodeaccess (e); - returnOldValue; the } - }Wuyi++Modcount; the if(++size >threshold) - resize (); Wu afternodeinsertion (evict); - return NULL; About}
1.3.2 Pop
- Returns null if there is a current key in the HashMap and returns its corresponding value
JDK1.8 version source code is as follows:
1 /**2 * Returns the value to which the specified key is mapped,3 * or {@codeNULL} If this maps contains no mapping for the key.4 *5 * <p>more Formally, if this map contains a mapping from a key6 * {@codek} to a value {@codeV} such that {@code(key==null? K==null:7 * Key.equals (k))}, then this method returns {@codev}; otherwise8 * It returns {@codenull}. (There can is at the most one such mapping.)9 *Ten * <p>a return value of {@codenull} does not <i>necessarily</i> One * indicate that the map contains No. mapping for the key; it ' s also A * Possible that the map explicitly maps the key to {@codenull}. - * The {@link#containsKey ContainsKey} operation is used to - * Distinguish these, cases. the * - * @see#put (Object, Object) - */ - PublicV get (Object key) { +Node<k,v>e; - return(E = getnode (hash (key), key) = =NULL?NULL: E.value; +}
Hashmap in Java