// 常量列表 DEFAULT_INITIAL_CAPACITY = 1 << 4; //The capacity is the number of buckets in the hash table MAXIMUM_CAPACITY = 1 << 30; /* **The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased. When the number of entries in the hash table exceeds the product of the load factor and the current capacity, the hash table is rehashed (that is, internal data structures are rebuilt) so that the hash table has approximately twice the number of buckets. */ DEFAULT_LOAD_FACTOR = 0.75f; //填充因子
put方法解析:
判断是否是空 table ,初始化
1 2 3
if (table == EMPTY_TABLE) { inflateTable(threshold); }
如果key == null 则通过遍历来设置其中的值,可知null不参与hash
1 2 3 4 5 6 7 8 9 10
for (Entry<K,V> e = table[0]; e != null; e = e.next) { if (e.key == null) { VoldValue= e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(0, null, value, 0);
进行hash运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14
finalinthash(Object k) { inth= hashSeed; if (0 != h && k instanceof String) { return sun.misc.Hashing.stringHash32((String) k); //猜测是为字符串做了优化提供的Hash,并没有追踪到里面的源代码 }
h ^= k.hashCode();
// This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded // number of collisions (approximately 8 at default load factor). h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }
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))) { VoldValue= e.value; e.value = value; e.recordAccess(this); return oldValue; } }
添加计数
1 2 3 4 5 6 7 8
modCount++; /** * 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). */
如果key不存在则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
addEntry(hash, key, value, i); returnnull;
voidaddEntry(int hash, K key, V value, int bucketIndex) { if ((size >= threshold) && (null != table[bucketIndex])) { //是否需要重新定义table的大小 resize(2 * table.length); hash = (null != key) ? hash(key) : 0; bucketIndex = indexFor(hash, table.length); }
createEntry(hash, key, value, bucketIndex); }
voidcreateEntry(int hash, K key, V value, int bucketIndex) { Entry<K,V> e = table[bucketIndex]; table[bucketIndex] = newEntry<>(hash, key, value, e); size++;//计数length }