Ответ
Да, разные (не равные по equals) объекты могут иметь одинаковый hashCode(). Это явление называется коллизией хэш-кода.
Причина: Метод hashCode() возвращает int (диапазон ~4.3 млрд значений), в то время как количество возможных объектов в Java практически неограниченно. По принципу Дирихле, совпадения неизбежны.
Контракт между equals() и hashCode():
- Если
a.equals(b)возвращаетtrue, тоa.hashCode()обязан быть равенb.hashCode(). - Обратное неверно: если
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.