Почему массив байтов (byte[]) нельзя использовать как ключ в HashMap?

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

Ответ

Массивы в Java не переопределяют методы equals() и hashCode(), наследуя их реализацию от класса Object. Это нарушает ключевой контракт для ключей в HashMap.

Проблема: Два разных массива с идентичным содержимым будут считаться разными ключами, так как Object.equals() сравнивает ссылки, а не содержимое.

byte[] key1 = {1, 2, 3};
byte[] key2 = {1, 2, 3}; // Идентичное содержимое

Map<byte[], String> map = new HashMap<>();
map.put(key1, "value1");

System.out.println(map.get(key2)); // Вывод: null
System.out.println(key1.equals(key2)); // Вывод: false (сравнение ссылок)
System.out.println(Arrays.equals(key1, key2)); // Вывод: true (сравнение содержимого)

Решение: Используйте объекты с корректной реализацией equals/hashCode:

  1. ByteBuffer (после вызова .flip() или .rewind()).
  2. List<Byte> (например, Arrays.asList(1, 2, 3) для оберток).
  3. Собственный класс-обертка для массива с переопределенными методами.
  4. String, если массив представляет текст (например, new String(bytes, StandardCharsets.UTF_8)).