SummaryClass inheritance Relationships
Java.lang.Object
java.util.abstractmap<k,v>
java.util.hashmap<k,v>
Defined
public class treemap<k,v>
extends abstractmap<k,v>
implements Navigablemap<k,v>, Cloneable, Serializable
Points
1) differs from Hashtable in that it is asynchronous, allowing null
2 The order is not guaranteed, even the order is not guaranteed to change over time
3 basic operation put, get constant time
4 The traversal operation is proportional to the capacity+size
5) HashMap performance is related to capacity and load factor, load factor is the ratio of the current element number to the capacity, usually set to 0.75, if this value is too large, the space utilization is high, but the likelihood of the conflict increases, which may lead to the discovery time increase Plus, if too small, conversely. When the number of elements is greater than capacity * load_factor, HASHMAP will reschedule the Hash table. Therefore, efficient use of HASHMAP requires estimating the number of elements, setting the best capacity and load factor, resulting in a decrease in the number of times the Hash table is rearranged. Implement capacity
Public HashMap (int initialcapacity, float loadfactor) {if (Initialcapacity < 0) throw new Illegalargumente
Xception ("Illegal initial capacity:" + initialcapacity);
if (initialcapacity > maximum_capacity) initialcapacity = maximum_capacity; if (loadfactor <= 0 | |
Float.isnan (Loadfactor)) throw new IllegalArgumentException ("Illegal load factor:" +
Loadfactor);
Find a power of 2 >= initialcapacity int capacity = 1;
while (capacity < initialcapacity) capacity <<= 1;
This.loadfactor = Loadfactor;
threshold = (int) math.min (capacity * Loadfactor, maximum_capacity + 1);
Table = new Entry[capacity];
usealthashing = sun.misc.VM.isBooted () && (capacity >= holder.alternative_hashing_threshold);
Init ();
}
Note that HASHMAP does not determine the capacity size according to the initialcapacity you specify, but instead finds a larger number and is 2 n Times Square.
Why do you have to be 2 n times? Hash
/** * Retrieve Object hash code and applies a supplemental hash function to the * result hash, which defends against R quality Hash functions. This are * critical because HASHMAP uses power-of-two length hash tables, that * otherwise encounter collisions for HASHC Odes that does not differ * in lower bits.
Note:null keys always map to hash 0, thus index 0.
* * Final int hash (Object k) {int h = 0;
if (usealthashing) {if (k instanceof String) {return Sun.misc.Hashing.stringHash32 ((String) k);
} h = hashseed;
} h ^= K.hashcode ();
This function ensures so hashcodes that differ only by//constant multiples in each bit position have a bounded
Number of collisions (approximately 8 at default load factor).
H ^= (H >>>) ^ (h >>> 12);
Return h ^ (H >>> 7) ^ (H >>> 4);
}
If K is a String type, a special hash function is used, otherwise the first gets hashcode, and then the H is shifted, XOR, or manipulated, and the problem is:
Why do we have to shift, vary or operate here?
At:
h = abcdefgh
H1 = h >>> = 00000abc
h2 = h >>> 0 = 000abcde
h3 = h1 ^ H2 = [] [0] [0] A [b] [A^c] [B^d] [C^e]
h4 = h ^ h3 = [A][b][c][a^d][b^e][a^c^f][b^d^g][c^e^h]
h5 = h4 >>> 4 = [0][a][b][c][a^d][b^e][a^c^f][b^d^g]
h6 = h4 >>> 7 = ([0][:3]) [0][0][a][b][c][a^d][b^e][a^c^f] ([a^c^f][0])
H7 = h4 ^ H6 = too cruel ...
Put
/** * Associates The specified value with the specified key into this map.
* If The map previously contained a mapping for the "key", the old * value is replaced. * * @param key key with which the specified value being associated * @param value value to being associated with the SPE Cified Key * @return The previous value associated with <tt>key</tt>, or * <tt>null</tt>
If there is no mapping for <tt>key</tt>. * (A <tt>null</tt> return can also indicate the map * previously associated <TT>NU
Ll</tt> with <tt>key</tt>.)
* * Public V-put (K key, V value) {if (key = null) return Putfornullkey (value);
int hash = hash (key);
int i = 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))) {V oldValue = E.value;E.value = value;
E.recordaccess (this);
return oldValue;
}} modcount++;
AddEntry (hash, key, value, I);
return null;
}
From put can actually see each