Какова ситуация, когда hashCode двух объектов равен друг другу, но == и equals () получат false?
Когда происходит коллизия хеш-кода.
Пример
Рассмотрим эти два длинных:
Long l1 = 1L;
Long l2 = 4294967296L; //which is 2 ^ 32
Согласны ли вы с тем, что есть разные и equals()
вернет false? Тем не менее, результат
l1.hashCode() == l2.hashCode()
верно.
Почему? Посмотрите на реализацию hashCode для Long
:
public static int hashCode(long value) {
return (int)(value ^ (value >>> 32));
}
Поскольку long может иметь 2 ^ 64 значения, а возвращаемое значение хеш-кода - это int, которое может иметь 2 ^ 32 значения, это нормально, если у вас есть коллизии (каждое значение создает коллизии с 2 ^ 32 другими значениями).
Разъяснения
Но я слышал, что override equals () тоже должно переопределять hashCode (),
так что этот вопрос не случится.
Да, когда вы переопределяете equals()
, вы должны переопределить также hashCode()
. Это правда, но я думаю, что вы перепутали последствия. Из Javadoc хэш-кода :
Если два объекта равны в соответствии с методом equals (Object), то вызов метода hashCode для каждого из двух объектов должен привести к одинаковому целочисленному результату.
Не требуется, чтобы, если два объекта были неравны
метод equals (java.lang.Object), затем вызывается метод hashCode
каждый из двух объектов должен давать разные целочисленные результаты.
Тем не менее, программист должен знать, что создание различных
целочисленные результаты для неравных объектов могут улучшить производительность
хеш-таблицы.
Итак, смысл
a.equals(b) => a.hashCode() == b.hashCode()
должно быть всегда верно (если ваши методы реализованы правильно), но обратное значение
a.hashCode() == b.hashCode() => a.equals(b)
не обязательно должен.