1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| 1. hashMap的大小始终是2的n次幂 2. 每扩充一次,HashMap 的容量就增大一倍。 3. hashMap的构造方法; * HashMap():构建一个初始容量为 16,负载因子为 0.75 的 HashMap。 * HashMap(int initialCapacity):构建一个初始容量为 initialCapacity,负载因子为 0.75 的 HashMap。 * HashMap(int initialCapacity, float loadFactor):以指定初始容量、指定的负载因子创建一个 HashMap。
// 以指定初始化容量、负载因子创建 HashMap public HashMap(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal load factor: " + loadFactor);
this.loadFactor = loadFactor; threshold = initialCapacity; init(); } 注意:此处用的java1.7源码,这里并没有在构造函数里面就把容量扩展到 比initialCapacity小的,最小的2的n次方值。 而是在put第一个元素的时候才执行这个操作,保证上述条件1 public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); //扩容到最2的n方 } ... } private void inflateTable(int toSize) { // Find a power of 2 >= toSize int capacity = roundUpToPowerOf2(toSize);
threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1); table = new Entry[capacity]; initHashSeedAsNeeded(capacity); } 增长: // 将 key、value 添加到 i 索引处 addEntry(hash, key, value, i);
void addEntry(int hash, K key, V value, int bucketIndex) { // 如果大小超过临界值,容量翻倍 if ((size >= threshold) && (null != table[bucketIndex])) { resize(2 * table.length); hash = (null != key) ? hash(key) : 0; bucketIndex = indexFor(hash, table.length); }
createEntry(hash, key, value, bucketIndex); }
void createEntry(int hash, K key, V value, int bucketIndex) { Entry<K,V> e = table[bucketIndex]; table[bucketIndex] = new Entry<>(hash, key, value, e); size++; }
|