- How is HASHMAP implemented?
- What did the put do?
- What did get do?
- Initialize capacity, full load rate, expansion?
- Hash
- Similar structures and similarities, different points?
Load factor full Load rate
Capacity capacity
Threshold Critical Value
ImportJava.util.Map; Public classTest { Public Static voidMain (string[] args) {Map<key, string> map =NewHashmap<key, string>(); Map.put (NewKey ("A"), "1"); Map.put (NewKey ("B"), "2"); Map.put (NewKey ("C"), "3"); SYSTEM.OUT.PRINTLN (map); }}classKey {PrivateString name; Key (String name) { This. Name =name; } @Override Public inthashcode () {return1; } @Override PublicString toString () {return"Key [name=" + name + "]"; }}
ImportJava.util.Map; Public classTest { Public Static voidMain (string[] args) {Map<key, integer> map =NewHashmap<key, integer>(); for(inti = 0; I < 11; i++) {Map.put (NewKey (System.nanotime ()), i); } System.out.println (map); }}classKey {Private Longname; Key (Longname) { This. Name =name; } @Override Public inthashcode () {return1; } @Override PublicString toString () {return"Key [name=" + name + "]"; }}
Static Final int Treeify_threshold = 8; Static Final int Untreeify_threshold = 6; Static Final int min_treeify_capacity = 64;
The critical value of the control treeify is 8, and when the chain in the bin is greater than 8 o'clock, try Treeify
- 1) If the table capacity is less than 64, the table will be enlarged. So when you add a 9th element, by 16->32, when you add the 10th element, the 32->64
- 2) When adding a 11th element, the TreeNode
==============================================
Put
FinalV Putval (intHash, K key, V value,BooleanOnlyifabsent,Booleanevict) {Node<k, v>[] tab; Node<k, v>p; intN, I; //1 table is empty when reset size if(tab = table) = =NULL|| (n = tab.length) = = 0) n= (Tab =resize ()). length; //2 Drop to empty bin add node directly if(p = tab[i = (n-1) & hash]) = =NULL) Tab[i]= NewNode (hash, key, value,NULL); //3 Fall to the non-empty bin, judging A, B, C, Else{Node<k, v>e; K K; //a) The header is the same as the entry key, replacing the old value if(P.hash = = Hash && (k = p.key) = = Key | | (Key! =NULL&&Key.equals (k)))) E=p; //b) header is red-black tree to add tree node Else if(pinstanceofTreeNode) e= ((treenode<k, v>) p). Puttreeval ( This, tab, hash, key, value); //c) The header is a chain Else { //traverse chain, check by item, Judge I, II for(intBincount = 0;; ++Bincount) { //I) Append node at the end and check if a red-black tree needs to be converted if((e = p.next) = =NULL) {P.next= NewNode (hash, key, value,NULL); if(Bincount >= treeify_threshold-1)//-1 for 1sttreeifybin (tab, hash); Break; } //II) Replace the old value with the same key to return if(E.hash = = Hash && (k = e.key) = = Key | | (Key! =NULL&&Key.equals (k)))) Break; P=e; } } if(E! =NULL) {//existing mapping for keyV OldValue =E.value; if(!onlyifabsent | | oldValue = =NULL) E.value=value; Afternodeaccess (e); returnOldValue; } } ++Modcount; //Extended Table X2 when the number of elements in the table is greater than the critical value if(++size >threshold) resize (); Afternodeinsertion (evict); return NULL; }
Get
FinalNode<k, V> GetNode (inthash, Object key) {Node<k, v>[] tab; Node<k, v>First , E; intN; K K; //table exists, header node exists if(tab = table)! =NULL&& (n = tab.length) > 0 && (first = tab[(n-1) & hash])! =NULL) { //same as Header node key, returns header node if(First.hash = = Hash && (k = first.key) = = Key | | (Key! =NULL&&Key.equals (k)))) returnFirst ; //If there is a child node of the header if((E = first.next)! =NULL) { //if the header is a red-black tree to fetch the tree node if(FirstinstanceofTreeNode)return(Treenode<k, v>). Gettreenode (hash, key); //if the header is a chain Do { //traverse the node and find the same key to return if(E.hash = = Hash && (k = e.key) = = Key | | (Key! =NULL&&Key.equals (k)))) returne; } while((E = e.next)! =NULL); } } //the same key was not found return NULL; }
Treeify
Final voidTreeifybin (node<k, v>[] tab,inthash) { intN, index; Node<k, v>e; //If table does not reach the minimum treeify capacity (64) then the expansion X2 if(Tab = =NULL|| (n = tab.length) <min_treeify_capacity) resize (); //when the header node exists Else if((E = Tab[index = (n-1) & hash])! =NULL) {TreeNode<k, v> HD =NULL, TL =NULL; //traverse Chain will Node ---TreeNode Do{TreeNode<k, v> p = Replacementtreenode (E,NULL); if(TL = =NULL) HD=p; Else{P.prev=tl; Tl.next=p; } TL=p; } while((E = e.next)! =NULL); if((Tab[index] = HD)! =NULL) //draw red and black treeshd.treeify (tab); } }
Resize
/** * Initializes or doubles table size. If null, allocates in * accord with initial capacity target held in field threshold. * Otherwise, because we is using power-of-two expansion, the * elements from each bin must either stay at same index, or move * with a power of both offset in the new table. * @return the table */ final node<k, v> [] Resize () { ... return newTab; }
Hash
/** * 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); }
Conjecture about abbreviations used in writing methods
- MC = Modcount
- tab = Table
- bin = Table[i]
- TL = Tree Left
- HD = Header
- p = Present
- i = Index
- Prev = Previous
- Next = Next
- K = key
- val = value
- v = value
- n = length
- E = Entry
- Simplify
- Tree-Treeify
- Undo
- Untreeify-Untreeify
Java.util.HashMap