/** * (The javadoc description is true upon serialization. * Additionally, if the table array has not been allocated, this * field holds the initial array capacity, or zero signifying * DEFAULT_INITIAL_CAPACITY.) * HashMap扩容阈值,并没有默认阈值,原因是阈值可由容量乘上负载因子计算而来(注释中有说明) * 计算公式:threshold = capacity * loadFactor */ int threshold;
/** * Constructs an empty {@code HashMap} with the default initial capacity * (16) and the default load factor (0.75). */ publicHashMap(){ this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted }
初始化一个哈希数组容量为initialCapacity,装载因子为0.75的HashMap
1 2 3 4 5 6 7 8 9 10
/** * Constructs an empty {@code HashMap} with the specified initial * capacity and the default load factor (0.75). * * @param initialCapacity the initial capacity. * @throws IllegalArgumentException if the initial capacity is negative. */ publicHashMap(int initialCapacity){ this(initialCapacity, DEFAULT_LOAD_FACTOR); }
/** * Constructs an empty {@code HashMap} with the specified initial * capacity and load factor. * * @param initialCapacity the initial capacity * @param loadFactor the load factor * @throws IllegalArgumentException if the initial capacity is negative * or the load factor is nonpositive */ publicHashMap(int initialCapacity, float loadFactor){ // 检查传入的初始容量是否合法 if (initialCapacity < 0) thrownew IllegalArgumentException("Illegal initial capacity: " + initialCapacity); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; // 检查装载因子是否合法 if (loadFactor <= 0 || Float.isNaN(loadFactor)) thrownew IllegalArgumentException("Illegal load factor: " + loadFactor); // 初始化装载因子 this.loadFactor = loadFactor; // 用初始容量信息来计算扩容门槛 this.threshold = tableSizeFor(initialCapacity); }
使用指定的HashMap中的元素来初始化一个新的HashMap
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/** * Constructs a new {@code HashMap} with the same mappings as the * specified {@code Map}. The {@code HashMap} is created with * default load factor (0.75) and an initial capacity sufficient to * hold the mappings in the specified {@code Map}. * * @param m the map whose mappings are to be placed in this map * @throws NullPointerException if the specified map is null */ publicHashMap(Map<? extends K, ? extends V> m){ this.loadFactor = DEFAULT_LOAD_FACTOR; // 将指定HashMap中的元素存入到当前HashMap(允许覆盖) putMapEntries(m, false); }
finalvoidputMapEntries(Map<? extends K, ? extends V> m, boolean evict){ int s = m.size(); if (s > 0) { // 如果当前HashMap的哈希数组还未初始化 if (table == null) { // pre-size // 根据HashMap中的元素数量反推哈希数组的最低容量要求 float ft = ((float)s / loadFactor) + 1.0F; // 注意这里!!!! int t = ((ft < (float)MAXIMUM_CAPACITY) ? (int)ft : MAXIMUM_CAPACITY); // 如果大于需要扩容的阈值,则重新计算扩容阈值 if (t > threshold) threshold = tableSizeFor(t); } else { // Because of linked-list bucket constraints, we cannot // expand all at once, but can reduce total resize // effort by repeated doubling now vs later // 由于链表存储桶的限制,我们无法一次全部扩展 // 但可以通过立即加倍与以后加倍来减少总的调整工作量 // 初始化哈希数组,或者对哈希数组扩容,并返回新的哈希数组 while (s > threshold && table.length < MAXIMUM_CAPACITY) resize(); } // 循环遍历进行添加,允许覆盖 for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) { K key = e.getKey(); V value = e.getValue(); putVal(hash(key), key, value, false, evict); } } }