Sobes.tech
Назад к вопросам
Junior — Middle
68

Какой объем памяти выделяется внутри HashSet для хранения двух элементов, один из которых имеет hashCode 0, а другой — 1000000?

Компании, где спрашивали
ЯндексЯндекс

Ответ от нейросети

sobes.tech AI

В Java HashSet реализован на основе HashMap, где элементы хранятся в виде ключей. Внутри HashMap используется массив бакетов (table), размер которого всегда степень двойки, по умолчанию 16.

При добавлении первого элемента HashSet выделит массив из 16 бакетов. Каждый бакет — это либо null, либо связанный список (или дерево, если элементов много).

Для двух элементов с hashCode 0 и 1000000:

  • Индекс бакета вычисляется как hash & (table.length - 1).
  • Для hashCode 0 индекс будет 0.
  • Для hashCode 1000000 (в двоичном виде) индекс будет 1000000 & 15.

1000000 в двоичном виде заканчивается на 0, значит индекс будет 0.

Таким образом, оба элемента попадут в один и тот же бакет (индекс 0), и внутри этого бакета будет связанный список из двух элементов.

Объем памяти:

  • Массив бакетов: 16 ссылок (каждая 4 или 8 байт в зависимости от JVM).
  • Два объекта Node (внутренние элементы HashMap), каждый содержит ключ, значение (для HashSet — фиктивное значение), ссылку на следующий элемент и hash.

Итого, выделяется массив из 16 элементов и два объекта узлов, связанных в цепочку в одном бакете.

Пример:

HashSet<Integer> set = new HashSet<>();
set.add(0);       // hashCode = 0
set.add(1000000); // hashCode = 1000000

Оба элемента будут в бакете с индексом 0, что может привести к ухудшению производительности при поиске.