Comments 18
Об ООП: не существует способа расширить класс, порождающий экземпляры, и добавить к нему новый аспект, сохранив при этом соглашения для метода equals. (с)
Спасибо вам за вопрос. Метод реализует отношение эквивалентности. Соглашения включают рефлексивность, симметричность, транзитивность, консистентность и отличие от нуля. Проблема: при добавлении аспекта нарушается хотя бы одно из этих соглашений.
Многие классы, включая классы коллекций, полагаются на то, что объекты, передаваемые им, подчиняются соглашениям (контракту) для этого метода.
…если только в методе базового класса нет сравнения типов. Но такое сравнение будет работать небыстро.
Реализация .hashcode() по умолчанию?
Насколько я понял, точно так никто в этом и не разобрался.
Ага, ага. Только ответ ищется за две минуты, и содержит ссылку на код. А для тех кто читал Хабр, прежде чем начал писать, несложно и на хабре найти парочку статей, гораздо глубже этой.
Легко проследить, что такое определение не противоречит математической идеологии.
Легко заметить, что противоречит:
симметричным (для любых x, y выполняется: если x = y, то y = x)
String a = "Test";
String b = null;
a.equals(b) // false
b.equals(a) // NPE
Строгую математическую семантику соблюдает Objects.equals(). И именно его нужно было использовать с самого начала для оператора "==". Однако создателям Java казалось очень важным каждый обращать внимание пользователей на то, как они реализовали equals(), и что сравнивать строки при помощи "==" в их языке хоть и можно, но будет неправильно. Даром что ссылочное сравнение используется в одном случае из ста. Но уж теперь ничего не поделаешь.
Пару замечаний чисто про математику:
Возможно есть такое элемент из X, и даже возможно не один, что он не сопоставлен никакому элементу из Y
тогда эта функция не определена на всём X. Другое дело что не всем Y могут найтись из X в hashCode, а это запросто. Тогда это не сюрьекция.
И второе: считаю уместным отметить, что любому отображению соответствует отношение эквивалентности по правилу: два элемента эквивалентны если и только если их образы отображений совпадают. Это даёт наглядный пример, как можно устроить equals через hashCode. Ни в коем случае к этому не призываю.
Верно и обратное: если есть отношение эквивалентности, то ему соответствует отображение исходного множества в его фактор-множество по этой эквивалентности. Но это так ;-)
Методы .equals и .hashcode в Java. Отличия реализации по умолчанию от реализации на практике