problem description
The resize () method of HashMap in JDK8 inJDK8, if you modify the loadFactor, may cause an error when you resize later.
in theory, threshold should always be equal to capacity * loadFactor, but in the resize () method, when capacity is greater than 16, it changes capacity to twice as much as threshold directly to twice as much. This approach is fine when loadFactor is the default, that is, 0.75. However, if you adjust the loadFactor, for example, change the loadFactor by 0.70, then there will be errors in this expansion method.
as shown in figure
I have verified the above data through debugging tests. I would like to ask, does anyone know why the designer of the class did not consider this situation, or deliberately ignored it?
related codes
partial source code of resize () function
// sizethreshold
final Node<K,V>[] resize() {
Node<K,V>[] oldTab = table;
int oldCap = (oldTab == null) ? 0 : oldTab.length;
int oldThr = threshold;
int newCap, newThr = 0;
if (oldCap > 0) { // oldCap0table0resize()
if (oldCap >= MAXIMUM_CAPACITY) { // oldCaptablecapacity
threshold = Integer.MAX_VALUE; // thresholdresize()
return oldTab;
}
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && // capacity
oldCap >= DEFAULT_INITIAL_CAPACITY) //
newThr = oldThr << 1; // double threshold // threshold2
//
}
//
else if (oldThr > 0) // initial capacity was placed in threshold initial capacity
// oldCapoldTabnulloldThrthresholdinitial capacity
newCap = oldThr; // newCapinitial capacity
// initial capacityinitial capacity0initial capacity
else { // zero initial threshold signifies using defaults
newCap = DEFAULT_INITIAL_CAPACITY;
newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
}
// initial capacitycapacityresize()
// resize()
if (newThr == 0) {
float ft = (float)newCap * loadFactor;
newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
(int)ft : Integer.MAX_VALUE);
}
threshold = newThr;