Ответ
Да, метод hashCode() остаётся семантически корректным даже при коллизиях. Коллизия не является ошибкой, это ожидаемая ситуация, которую обязаны корректно обрабатывать структуры данных, такие как HashMap или HashSet.
Ключевые контракты hashCode():
- Если два объекта равны по
equals(), ихhashCode()должны быть равны. - Если два объекта не равны по
equals(), ихhashCode()могут быть равны (это и есть коллизия).
Пример коллизии:
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:
- Каждая ячейка (bucket) внутреннего массива
HashMapможет хранить несколько элементов. - При коллизии элементы с одинаковым хэшем помещаются в одну ячейку в виде связного списка (или сбалансированного дерева, если элементов много).
- При поиске по ключу сначала вычисляется хэш, находится нужная ячейка, а затем в списке/дереве этой ячейки выполняется линейный поиск с проверкой
equals().
Следствие: Коллизии не нарушают корректность, но снижают производительность, превращая операцию поиска из O(1) в O(n) в худшем случае для одной ячейки.