The resize () method of HashMap in JDK8 may cause errors if load factor is modified.

problem description

The resize () method of HashMap in JDK8 in

JDK8, 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;
Jul.11,2022

although the absolute value of the error is increasing, the proportion is always very small

Menu