Ответ
Да, могут. В Java/Котлине hashCode() возвращает int, а количество возможных хэш-кодов ограничено (2^32), тогда как количество объектов потенциально бесконечно. Это называется коллизией хэш-кодов.
Пример:
val str1 = "Aa"
val str2 = "BB"
println(str1.hashCode()) // 2112
println(str2.hashCode()) // 2112
Важно: при переопределении hashCode() нужно соблюдать контракт:
- Если
a.equals(b)== true, тоa.hashCode() == b.hashCode() - Обратное не обязательно - разные объекты могут иметь одинаковый хэш
Ответ 18+ 🔞
Э, слушай, а вот тут интересный момент вылезает, про который многие забывают. Могут ли два разных объекта в Java или Kotlin иметь одинаковый hashCode()? Да, блядь, конечно могут, это же элементарно! Это называется коллизией хэш-кодов, и это не баг, а фича, ёпта.
Смотри, в чём прикол: hashCode() возвращает int, а это, если кто забыл, всего-то 2^32 возможных значения. А объектов-то мы можем наделать — овердохуища! Бесконечность, по сути. Ну и как, по-твоему, все они влезут в эти скромные 4 миллиарда комбинаций? Правильно, никак. Поэтому коллизии — это неизбежное зло, как пробки в час пик.
Вот, на, простой пример, чтобы мозги не взрывались:
val str1 = "Aa"
val str2 = "BB"
println(str1.hashCode()) // 2112
println(str2.hashCode()) // 2112
Видишь? Две абсолютно разные строки, а хэш один и тот же. Удивление пиздец, да? Но так и задумано.
Теперь главное, что многие распиздяи упускают, когда сами начинают hashCode() переопределять. Есть, блядь, контракт, который нарушать нельзя, а то потом искать ничего не будешь, и коллекции на тебя обижаться начнут.
Контракт простой, как три копейки:
- Если
a.equals(b)вернулtrue(объекты равны), то иa.hashCode()обязан быть равенb.hashCode(). Это железное правило, иначе всё полетит к чертям собачьим. Представь, положил ты объект вHashSetпо одному хэшу, а искать его будешь по другому — доверия ебать ноль к такой структуре. - А вот обратное — НЕ обязательно. Если хэши совпали, это не значит, что объекты равны. Как раз наш пример со строками "Aa" и "BB" это прекрасно демонстрирует. Разные объекты, одинаковый хэш — живут, не тужат. Коллекции с этим умеют работать.
Так что запомни: делаешь equals() — переопределяй и hashCode(), и делай это так, чтобы равные объекты давали одинаковый хэш. А уж разные пусть иногда и совпадают — с этим система справится. Главное — не накосячить с первым пунктом, а то будет тебе хиросима в коде.