Интерфейс Comparator<SomeClass>
реализован как отдельный класс для класса SomeClass
.Нет необходимости, чтобы SomeClass.equals(Object)
соответствовал компаратору.(Действительно, было бы в значительной степени побеждать цель иметь отдельный объект сравнения!)
С другой стороны, если SomeClass
реализует Comparable<SomeClass>
, то настоятельно рекомендуется , что equals(Object)
и compare(SomeClass, SomeClass)
, чтобы быть последовательными.В javadoc для Comparable
говорится следующее:
"Настоятельно рекомендуется (хотя и не обязательно), чтобы естественные упорядочения были совместимы с равными.наборы (и отсортированные карты) без явных компараторов ведут себя «странно», когда они используются с элементами (или ключами), естественное упорядочение которых несовместимо с равенством. В частности, такой отсортированный набор (или отсортированная карта) нарушает общий контракт для набора (или map), который определяется в терминах метода equals. "
" Например, если добавить два ключа a и b, например (!a.equals(b) && a.compareTo(b) == 0)
, к отсортированному набору, который выполняетЕсли не использовать явный компаратор, вторая операция добавления возвращает значение false (и размер отсортированного набора не увеличивается), поскольку a и b эквивалентны с точки зрения отсортированного набора. "
Компилятор Java не будет жаловаться, если я этого не сделаю.
Компилятор Java не может определить, совместимы ли equals
и compare
.(Или equals
и hashcode
в этом отношении.) Теоретически невозможно сделать это во всех случаях и за пределами "уровня техники" на практике.А простой тест, который вы переопределили equals
, в некоторых случаях выдаст ложные предупреждения.
Вы не можете полагаться на компилятор, чтобы указать на логические ошибки в вашем приложении.
Если вопрос на самом деле касается семантики Comparable<T>.equals(Object)
, то ответ в javadocs:
"Обратите внимание, что всегда безопасно не переопределять Object.equals (ObjectОднако, переопределение этого метода может, в некоторых случаях, улучшить производительность, позволяя программам определять, что два разных компаратора устанавливают один и тот же порядок. "
Тед Хопп прокомментировал так:
"На самом деле, Comparator полезен для сортировки; нет причин, по которым согласование его с equals () могло бы« победить цель ». В общем, хорошая идея сделать их согласованными, хотя этоэто не требование. "
Во-первых, Тед неправильно истолковывает то, что я написал.Я сказал:
"Это ..." (то есть гипотетическое требование согласованности между T.equals (Object) и Comparator.compare (T, T) `" ... уничтожило бы цель иметь отдельный компаратор "
Во-вторых, это ни хорошая идея, ни плохаяИдея, чтобы компараторы были согласованы с равными. Это полностью зависит от предполагаемой семантики равных и предполагаемой цели компаратора.
Если компаратор используется для упорядочивания элементов в TreeSet, тогда несоответствие с equals
приведет к странному поведению.
Если компаратор используется для упорядочивания списка объектов для целей отображения, то согласованность с equals
вероятнабыть неуместным.