Зачем использовать поле `threshold` для хранения начальной емкости вместо дополнительного поля, такого как `initialCapacity`, которое понятнее?

#java #hashmap

#java #hashmap

Вопрос:

Конструктор HashMap

 /**
 * Constructs an empty <tt>HashMap</tt> with the specified initial
 * capacity and load factor.
 *
 * @param  initialCapacity the initial capacity
 * @param  loadFactor      the load factor
 * @throws IllegalArgumentException if the initial capacity is negative
 *         or the load factor is nonpositive
 */
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;
    this.threshold = tableSizeFor(initialCapacity); // here, threadshold is actually initial capacity
}
  

Я немного запутался при чтении кода. Мой вопрос в том, почему использование поля threshold для хранения начальной емкости вместо дополнительного поля, такого initialCapacity , которое понятнее?


Редактировать: я не заметил, что конструктор принимает параметр initialCapacity , я думаю, что параметр конструктора initialCapacity должен быть specifiedInitialCapacity .

Комментарии:

1. на самом деле, threshold = tableSizeFor(initialCapacity); если этот метод не просто: private int tableSizeFor(int value) { возвращаемое значение; }, обязательно будет разница

2. Мы говорим об этом tableSizeFor ?

3. @lealceldeiro Да.

4. initialCapacity передается в метод tableSizeFor() , который, вероятно, выполняет некоторые вычисления. Чтобы отразить, что параметр initialCapacity и поле threshold имеют разное значение, используется новое имя. Если бы вы назвали поле initialCapacity , вы бы смутили многих людей.

Ответ №1:

Потому что хэш-карты увеличиваются более одного раза, а пороговое значение является динамическим значением. Оно меняется в течение жизненного цикла карты и адаптируется при изменении размера карты.

Javadoc для threshold (1.8 openjdk):

 /**
 * The next size value at which to resize (capacity * load factor).
 *
 * @serial
 */
// (The javadoc description is true upon serialization.
// Additionally, if the table array has not been allocated, this
// field holds the initial array capacity, or zero signifying
// DEFAULT_INITIAL_CAPACITY.)
int threshold;
  

Поскольку размер карты можно изменять, начальная емкость именно такая, а пороговое значение остается неизменным только изначально.