Могут ли разные объекты в Java иметь одинаковый hashCode()?

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

Ответ

Да, разные (не равные по equals) объекты могут иметь одинаковый hashCode(). Это явление называется коллизией хэш-кода.

Причина: Метод hashCode() возвращает int (диапазон ~4.3 млрд значений), в то время как количество возможных объектов в Java практически неограниченно. По принципу Дирихле, совпадения неизбежны.

Контракт между equals() и hashCode():

  1. Если a.equals(b) возвращает true, то a.hashCode() обязан быть равен b.hashCode().
  2. Обратное неверно: если a.hashCode() == b.hashCode(), то a.equals(b) может быть как true, так и false.

Пример коллизии для строк:

String s1 = "Aa";
String s2 = "BB";

System.out.println(s1.hashCode()); // 2112
System.out.println(s2.hashCode()); // 2112
System.out.println(s1.equals(s2)); // false
// Хэш-функция для строк дала одинаковый результат для разных значений.

Последствия и обработка:

  • Коллизии — нормальное явление, с которым хэш-таблицы (HashMap, HashSet) справляются.
  • При коллизии элементы помещаются в одну корзину и хранятся в виде связного списка или дерева (в Java 8+).
  • Задача «хорошей» хэш-функции — минимизировать вероятность коллизий для неравных объектов, равномерно распределяя значения по диапазону int.