In the previous section, we talked about how to implement HashMap with hashes and lists, one of which has some answers today, why use a linked list instead of an array
The role of the list has the following two points benefits
1. Remove operation is high efficiency, only maintain the change of the pointer, no need to shift operation
2. When re-hashing, the original elements scattered in the same slot may be scattered in different places, for the array needs to be shifted operation, and the linked list just maintain the pointer
The method of dealing with the array length is not enough today
Table is a hash array
1. First define a non-modifiable static variable to store the table's initial size default_initial_capacity
2. Define a global variable to store the actual element length of the table, size
3. Define a global variable storage critical point, that is, when the size>=threshold of the element is critical, the capacity of the table is enlarged
4. Because index is calculated based on the length of the hash and table, you also need to re-hash all the elements
PackageSourcecoderead.collection.map; Public classEntryhashmap<k, v> { /**Initial capacity*/ Static Final intDefault_initial_capacity = 16; Static Final floatDefault_load_factor = 0.75f; /**critical value for next expansion*/ intthreshold; transient intsize; Final floatLoadfactor; transiententry[] table; PublicEntryhashmap () { This. Loadfactor =Default_load_factor; Threshold= (int) (Default_initial_capacity *default_load_factor); Table=NewEntry[default_initial_capacity]; } Publicv put (K key, V value) {//calculate a new hash inthash =Hash (Key.hashcode ()); //calculate the array of small labels I inti =indexfor (hash, table.length); //Traverse Table[i], if table[i] is not equal to the newly added key, the new join//a value of entry in Table[i], otherwise overwrites the old value with the new value and returns the old value for(entry<k, v> e = table[i]; E! =NULL; E =e.next) {Object k; if(E.hash = = Hash && (k = e.key) = = Key | |Key.equals (k))) {V OldValue=E.value; E.value=value; returnOldValue; }} addentry (hash, key, value, I); return NULL; } PublicV get (K key) {//calculate a new hash inthash =Hash (Key.hashcode ()); //calculate the array of small labels I inti =indexfor (hash, table.length); for(entry<k, v> e = table[i]; E! =NULL; E =e.next) {Object k; if(E.hash = = Hash && (k = e.key) = = Key | |Key.equals (k))) { returnE.value; } } return NULL; } Private voidAddEntry (intHash, K key, V value,intBucketindex) {Entry<k, v> e =Table[bucketindex]; //inserting new elements into the front of the listTable[bucketindex] =NewEntry<>(hash, key, value, E); if(size++ >=threshold) Resize (2 *table.length); } voidResizeintnewcapacity) {entry[] oldtable=table; intOldcapacity =oldtable.length; Entry[] NewTable=NewEntry[newcapacity]; Transfer (newtable); Table=newtable; Threshold= (int) (Newcapacity *loadfactor); } voidtransfer (entry[] newtable) {entry[] src=table; intNewcapacity =newtable.length; for(intj = 0; J < Src.length; J + +) {Entry<k, v> e =Src[j]; if(E! =NULL) {Src[j]=NULL; Do{Entry<k, v> next =E.next; inti =indexfor (E.hash, newcapacity); E.next=Newtable[i]; Newtable[i]=e; E=Next; } while(E! =NULL); } } } /*** Get the corresponding array subscript by hash code and the length of table * *@paramh *@paramlength *@return */ Static intIndexfor (intHintlength) { returnH & (length-1); } /*** A new hash value is calculated by a certain algorithm * *@paramh *@return */ Static intHashinth) {h^= (H >>>) ^ (H >>> 12); returnH ^ (H >>> 7) ^ (H >>> 4); } Public Static voidMain (string[] args) {Entryhashmap<string, string> HashMap =NewEntryhashmap<string, string>(); Hashmap.put ("Key", "value"); System.out.println (Hashmap.get ("Key")); }}
Come with me read the hashmap of Java source Code (III)