Когда HashMap в Java увеличивает количество бакетов (емкость)?

«Когда HashMap в Java увеличивает количество бакетов (емкость)?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

HashMap увеличивает свой внутренний массив бакетов (емкость, capacity) в процессе операции рехеширования (rehashing). Это происходит, когда количество добавленных элементов (size) превышает пороговое значение (threshold).

Порог рассчитывается по формуле:
threshold = capacity * loadFactor

  • loadFactor (коэффициент загрузки) по умолчанию равен 0.75.
  • capacity (ёмкость) всегда является степенью двойки.

Процесс:

  1. При добавлении нового элемента проверяется условие: if (size > threshold).
  2. Если условие истинно, capacity увеличивается вдвое (например, с 16 до 32).
  3. Создаётся новый массив бакетов нового размера.
  4. Все существующие элементы пересчитываются (рехешируются) и перераспределяются по новым бакетам.

Пример:

// Начальная capacity = 16, threshold = 16 * 0.75 = 12
HashMap<String, Integer> map = new HashMap<>();

for (int i = 0; i < 12; i++) {
    map.put("key" + i, i); // size = 12, threshold = 12 -> условие НЕ выполнено
}
// Добавление 13-го элемента
map.put("key12", 12); // size (13) > threshold (12) -> ВЫПОЛНЕНО
// Запускается рехеширование: capacity становится 32, threshold = 32 * 0.75 = 24

Практическая рекомендация: Если известно приблизительное количество элементов N, задавайте начальную capacity как N / loadFactor, чтобы избежать дорогостоящего рехеширования: new HashMap<>((int) (N / 0.75f) + 1).