Before we extend a set set to a map by inheriting a haseset. In fact, our expanded map is essentially a hashmap.
There are a lot of similarities between HashMap and HashSet, hashset use hash algorithm to determine the storage location of collection elements, so as to ensure a fast save, take the collection elements. For HashMap only, the system will only value as a key appendage, the system uses the hash algorithm to determine the storage location of key, so you can guarantee the fast save, take the set key, and value is always as a key of the subordinate.
hashmap<string,double> map = new hashmap<string,double> ();
Map.put ("Java", 100);
For code like above, when executing map.put ("Java", 100); The system will invoke the Hashcode () method of "Java" to get its hashcode () value. The storage location is then determined according to the Hashcode value system.
HashMap class of Put (K key,v value) method Source:
/** * The table, resized as necessary.
Length must Always is a power of two. * * transient entry<k,v>[] table = (entry<k,v>[]) empty_table; Used to store entry final float Loadfactor;
Load factor when the proportion of the array capacity exceeds the load factor, the array expands. Static Class Entry<k,v> implements Map.entry<k,v> {final K key; Used to store key V value; Used to store value entry<k,v> next; Used to point to: the same hashcode key, but the different key object int hash;
The hashcode value of the Key object/** * Creates new entry.
*/Entry (int h, K K, v V, entry<k,v> N) {value = V;
Next = n;
key = k;
hash = h;
'} ' public V ' put (K key, V value) {if (table = = empty_table) { Inflatetable (threshold);
//When key is null, call Putfornullkey to process if (key = null) return Putfornullkey (value);
Calculates the hash value int hash = hash (key) according to the key hashcode;
Search to develop hash values in the index of table int i = indexfor (hash, table.length); If I index is not null.
The next element of the E element for (entry<k,v> e = table[i]; e!= null; e = E.next) is continuously traversed by loops {Object K; Find the specified key equal to the key (that is, the hash value is the same, equals returns True) if (E.hash = Hash && (k = e.key) = = Key | |
Key.equals (k))) {V oldValue = E.value;
E.value = value;
E.recordaccess (this);
return oldValue; }//If the entry at the I index is null. Show no entry this time.
Directly inserted in this can be modcount++;
Add Key,value to index I at AddEntry (hash, key, value, I); ReturnNull }
The above code uses an important internal interface map.entry, each map.entry is actually a key-value. From the source of the HashMap can also be seen, the program has not considered the value of map.entry, but only the key, that is, according to the key to calculate the entry storage location. It also comes to the conclusion that the value of the map set can be used as an appendage of the key, and the value is determined when the system determines the storage location of the key.
From the HashMap put method source code can also be seen, when the program tries to place a key-value pair into the HashMap, first based on the key hashcode () return value to determine the storage location of the entry, if two key hash values are the same, Then they are stored in the same location. If the Equalus comparison of this two key returns True. The value of the newly added entry will be overwritten by the original entry Value,key. If these two equals return false, then the two entry will form a entry chain, and the newly added entry is located in the head of the entry chain.
If the equals of key returns True, then their hash value must be the same. That is, when the hashcode () is the same, the system calls equals again to determine whether to overwrite or form the entry chain.
The above program still calls the AddEntry (hash,key,value,i), the code. Where AddEntry is a method that HashMap provides for a package access, which is used only to add a key-value pair. The source code is as follows:
void AddEntry (int hash, K key, V value, int bucketindex) {
//Get Entry
entry<k,v> e = Table[buc at the specified bucketindex Ketindex];
Place the newly created Entry into the Bucketindex index and let the new Entry point to the original Entry
Table[bucketindex] = new entry<k,v> (hash, key, value, e);
If the number of key-value pairs in the map exceeds the limit if
(size++>=threshold) {
//Expanded Table object length to twice times
Resize (2*table.length);
}
The code above has a very elegant design, and the system always places the newly added entry object at the Bucketindex index. If there is already a entry object at the Bucketindex index. The newly added entry point to the entry (that is, to produce a entry chain). If there is no entry object at Bucketindex, the above code e variable is null. That is, the newly placed entry object points to null, that is, the entry chain is not generated.