/** * The default initial capacity - MUST be a power of two. * 默认的初始容量,必须是二的次方 */ staticfinalint DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
/** * The maximum capacity, used if a higher value is implicitly specified * by either of the constructors with arguments. * MUST be a power of two <= 1<<30. * * 最大容量,当通过构造函数隐式指定了一个大于MAXIMUM_CAPACITY的时候使用 */ staticfinalint MAXIMUM_CAPACITY = 1 << 30;
/** * The load factor used when none specified in constructor. * 加载因子,当构造函数没有指定加载因子的时候的默认值的时候使用 */ staticfinalfloat DEFAULT_LOAD_FACTOR = 0.75f;
/** * The bin count threshold for using a tree rather than list for a * bin. Bins are converted to trees when adding an element to a * bin with at least this many nodes. The value must be greater * than 2 and should be at least 8 to mesh with assumptions in * tree removal about conversion back to plain bins upon * shrinkage. * * TREEIFY_THRESHOLD为当一个bin从list转化为tree的阈值,当一个bin中元素的总元素最低超过这个值的时候,bin才被转化为tree; * 为了满足转化为简单bin时的要求,TREEIFY_THRESHOLD必须比2大而且比8要小 */ staticfinalint TREEIFY_THRESHOLD = 8;
/** * The bin count threshold for untreeifying a (split) bin during a * resize operation. Should be less than TREEIFY_THRESHOLD, and at * most 6 to mesh with shrinkage detection under removal. * * bin反tree化时的最大值,应该比TREEIFY_THRESHOLD要小, * 为了在移除元素的时候能检测到移除动作,UNTREEIFY_THRESHOLD必须至少为6 */ staticfinalint UNTREEIFY_THRESHOLD = 6;
/** * The smallest table capacity for which bins may be treeified. * (Otherwise the table is resized if too many nodes in a bin.) * Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts * between resizing and treeification thresholds. * * 树化的另外一个阈值,table的长度(注意不是bin的长度)的最小得为64。为了避免扩容和树型结构化阈值之间的冲突,MIN_TREEIFY_CAPACITY 应该最小是 4 * TREEIFY_THRESHOLD */ staticfinalint MIN_TREEIFY_CAPACITY = 64;
/** * The table, initialized on first use, and resized as * necessary. When allocated, length is always a power of two. * (We also tolerate length zero in some operations to allow * bootstrapping mechanics that are currently not needed.) * * table,第一次被使用的时候才进行加载 */ transient Node<K,V>[] table;
/** * Holds cached entrySet(). Note that AbstractMap fields are used * for keySet() and values(). * 键值对缓存,它们的映射关系集合保存在entrySet中。即使Key在外部修改导致hashCode变化,缓存中还可以找到映射关系 */ transient Set<Map.Entry<K,V>> entrySet;
/** * The number of key-value mappings contained in this map. * table中 key-value 元素的个数 */ transientint size;
/** * The number of times this HashMap has been structurally modified * Structural modifications are those that change the number of mappings in * the HashMap or otherwise modify its internal structure (e.g., * rehash). This field is used to make iterators on Collection-views of * the HashMap fail-fast. (See ConcurrentModificationException). * * HashMap在结构上被修改的次数,结构上被修改是指那些改变HashMap中映射的数量或者以其他方式修改其内部结构的次数(例如,rehash)。 * 此字段用于使HashMap集合视图上的迭代器快速失败。 */ transientint modCount;
/** * The next size value at which to resize (capacity * load factor). * * 下一次resize扩容阈值,当前table中的元素超过此值时,触发扩容 * threshold = capacity * load factor * @serial */ // (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.(???????)) int threshold;
/** * The load factor for the hash table. * 负载因子 * @serial */ finalfloat loadFactor;
/** * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return the previous value associated with key, or * null if there was no mapping for key. * (A null return can also indicate that the map * previously associated null with key.) * 返回先前key对应的value值(如果value为null,也返回null),如果先前不存在这个key,那么返回的就是null; */ public V put(K key, V value){ return putVal(hash(key), key, value, false, true); } / * 在往haspmap中插入一个元素的时候,由元素的hashcode经过一个扰动函数之后再与table的长度进行与运算才找到插入位置,下面的这个hash()方法就是所谓的扰动函数 * 作用:让key的hashCode值的高16位参与运算,hash()方法返回的值的低十六位是有hashCode的高低16位共同的特征的 * 举例 * hashCode = 0b 00100101101011000011111100101110 * * 0b 00100101101011000011111100101110 ^ * 0b 00000000000000000010010110101100 * 0b 00100101101011000001101010000010 */ staticfinalinthash(Object key){ int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }