Hashmap capacity does not increase even when threshold is reached

Java doc says - When the number of entries in a hash table exceeds the product of the load factor and current capacity, the hash table is rephrased

In the program below -

HashMap<Integer, String> map = new HashMap<Integer, String>(); int i = 1; while(i<16) { map.put(i, new Integer(i).toString()); i++; } 

The key is of type Integer, when inserting from the 13th to the 15th element, the HashMap capacity remains equal to 16, and the threshold remains the same as 12, why?

Debugging a screenshot after adding the 13th element on the map -

 args String[0] (id=16) map HashMap<K,V> (id=19) entrySet null hashSeed 0 KeySet null loadFactor 0.75 modCount 13 size 13 table HashMap$Entry<K,V>[16] (id=25) threshold 12 values null i 14 [null, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9, 10=10, 11=11, 12=12, 13=13, null, null] 

HashMap with a key of type String - HashMap<String, String> or a custom class - Map<Employee,Integer> shows the expected behavior on the 13th insert

+7
java hashmap threshold
source share
1 answer

It seems that this behavior is due to a change in the internal implementation of the HashMap PUT method in the latest version of Java 7. After passing through the source code of several versions, I found the answer to my question

The hashMap put method calls addEntry () to add a new record -

 public V put(K key, V value) { ... int hash = hash(key); int i = indexFor(hash, table.length); ... addEntry(hash, key, value, i); ... } 

jdk7-b147 The HashMap.addEntry method looks like

 addEntry(int hash, K key, V value, int bucketIndex) { Entry<K,V> e = table[bucketIndex]; table[bucketIndex] = new Entry<>(hash, key, value, e); if (size++ >= threshold) resize(2 * table.length); } 

The source code of version 1.7.0_67-b01 looks like

 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); } 

Thus, in recent versions of Java, the HashMap cannot be changed depending on the threshold. If the bucket is empty, recording will continue without resizing the HashMap

Java 8 may have different behavior, source code version 8-b132 shows that PUT is completely repeated -

 put(K key, V value) { return putVal(hash(key), key, value, false, true); } putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; .... } final Node<K,V>[] resize() { //many levels of checks before resizing } 

A Java document cannot be updated as often as Java versions! Thanks Steven

+5
source share

All Articles