Какой начальный размер (емкость) у HashMap в Java?

Ответ

Начальная емкость (количество корзин/buckets) по умолчанию для HashMap в Java — 16.

Ключевые детали:

  • Значение задано константой DEFAULT_INITIAL_CAPACITY = 16 в классе java.util.HashMap.
  • Емкость можно задать явно через конструктор:
    // HashMap с начальной емкостью 32
    Map<String, Integer> map = new HashMap<>(32);
  • HashMap внутренне округляет указанную емкость до ближайшей степени двойки (например, 50 -> 64). Это оптимизирует вычисление индекса корзины через побитовые операции.

Как работает рост:

  • Параметр loadFactor (коэффициент загрузки) по умолчанию равен 0.75.
  • При достижении порога емкость * loadFactor (для емкости 16 это 12 элементов) HashMap автоматически удваивает свою емкость и перераспределяет все элементы (rehashing).

Ответ 18+ 🔞

Ну слушай, вот сидишь ты, пишешь свой код, и тут бац — нужно HashMap создать. А ты даже не задумываешься, что у него там внутри изначально происходит. А там, между прочим, целая история!

Изначально, когда ты просто пишешь new HashMap<>(), внутри создаётся 16 корзин (этих самых buckets). Просто потому, что так решили мудрые дядьки из Oracle. Константа там называется DEFAULT_INITIAL_CAPACITY, и равна она, как ты уже догадался, 16. Ну, стандартная степень двойки, всё как мы любим.

Но если ты заранее знаешь, что запихнёшь туда овердохуища элементов, то можно и покомандовать:

Map<String, Integer> map = new HashMap<>(32);

Типа, "эй, HashMap, будь добр, стартуй сразу с 32 корзин, чтобы мне потом не дергаться". Однако, не всё так просто, ёпта! HashMap — хитрая жопа. Он твою цифру возьмёт, посмотрит на неё свысока и скажет: "Ага, 32 — это хорошо, это степень двойки. А вот 50? 50 — это хуйня. Сейчас я её округлю до ближайшей степени двойки, то есть до 64". И всё, приехали. Делает он это не из вредности, а чтобы быстрее индекс корзины вычислять через побитовые операции, без этих ваших медленных делений по модулю.

А теперь самое интересное — когда же эта штука начинает расти? А растёт она, когда наступает на грабли. Есть у него такой параметр — loadFactor (коэффициент загрузки). По умолчанию он 0.75. Это значит, что когда количество элементов превысит ёмкость * 0.75, начнётся пиздец, извините, рехешинг.

Для стандартных 16 корзин порог будет 16 * 0.75 = 12. Как только ты вставишь 13-й элемент — всё, ёперный театр! HashMap в панике удваивает количество корзин (становится 32), и начинает судорожно перетряхивать все уже существующие элементы, раскидывая их по новым местам. Операция, надо сказать, не из быстрых.

Так что мораль истории: если ты примерно прикидываешь, сколько элементов будет, — укажи начальную ёмкость в конструкторе. Сэкономишь немножко производительности, и нервы себе, и HashMap-у. А то он тебе в самый ответственный момент возьмёт и устроит эту весёлую движуху с переездом.