Реализация метода равных с использованием CompareTo

Общий вопрос: при реализации переопределения по умолчаниюequals метод в Java, какие проблемы я должен иметь о простом использовании уже реализованногоcompareTo метод против записи независимой логики в метод equals? Я заметил, что кто-то упомянул в другом вопросе, чтоfoo.equals((String)null) возвращает ложь, тогда какString.compareTo((String)null) бросаетNullPointerException, Что делает эти противоречивые результаты идеальной функциональностью?

Образецequals метод:

@Override
public boolean equals(Object obj) {
    if (obj != null && obj instanceof MyClass) {
        MyClass msg = (MyClass)obj;
        return this.compareTo(msg) == 0;
    }
    return false;
}

Редактировать: Цитата из документации насравнимый

Говорят, что естественный порядок для класса C согласован с equals тогда и только тогда, когда e1.compareTo (e2) == 0 имеет то же логическое значение, что и e1.equals (e2) для всех e1 и e2 класса C. Обратите внимание, что null не является экземпляром какого-либо класса, и e.compareTo (null) должен выдавать исключение NullPointerException, даже если e.equals (null) возвращает false

Редактировать:

После дальнейшего рассмотрения, я считаю, чтосравнимый документация также гласит следующее:

Разработчик должен обеспечить sgn (x.compareTo (y)) == -sgn (y.compareTo (x)) для всех x и y. (Это означает, что x.compareTo (y) должно вызвать исключение, если y.compareTo (x) генерирует исключение.)

Эрго, так какnull.compareTo(x) очевидно бросаетNPE,x.compareTo(null) следует также бросить NPE. Принимая во внимание, что для равных это не обязательно так. Я довольно хорошо разбираюсь в правильном обращении с NPE, поэтому считаю это довольно значительным.

 fge29 мая 2013 г., 16:45
Обратите внимание, что в то время как, в идеале,.compareTo() должно соответствовать.equals()Это ни в коем случае не является гарантией. УвидетьBigDecimal например. И да,null обработка, если вы идете по этому маршруту, может быть проблемой.
 Eric Jablow29 мая 2013 г., 18:17
Double.NaN имеет удивительное поведение для обоихequals(Object) а также .compareTo(Double)NaN.equals(NaN) являетсяtrue, ноNaN == NaN являетсяfalse, Так же,NaN самый большойDouble вcompareTo звонки и.NaN.compareTo(NaN) == 0equals согласуется сcompareTo, ноDouble В этом случае объект не соответствует стандартам IEEE. Необходимо, но удивительно.

Ответы на вопрос(2)

Решение Вопроса

Разница междуequals() а такжеcompareTo() в том, чтоequals() просто проверяет, равны ли два объекта друг другу, гдеcompareTo() используется для определения естественного порядка экземпляров указанного класса. Такжеequals() Метод имеет контракт сhashCode() метод ноcompareTo() hasn»т.

В соответствии сJavaDoc:

Обратите внимание, что null не является экземпляром какого-либо класса, и e.compareTo (null) должен выдать исключение NullPointerException, даже если e.equals (null) возвращает false.

Настоятельно рекомендуется, но не обязательно, чтобы (x.compareTo (y) == 0) == (x.equals (y)). Вообще говоря, любой класс, который реализует интерфейс Comparable и нарушает это условие, должен четко указывать на этот факт. Рекомендуемый язык "Примечание: у этого класса есть естественный порядок, который не совпадает с ".

Вы можете свободно использовать повторноcompareTo() метод логики в вашемequals() метод, но имейте в виду все контракты с,equals()hashCode() и контракт с JavaDoc дляcompareTo() метод. Если они не конфликтуют друг с другом, тогда продолжайте.

Я считаю, что обеспечение исполнения контрактов является более важным моментом ».

 AnthonyW29 мая 2013 г., 17:47
Я думаю, что соблюдение контрактов является более важным моментом. " <- Я могу определенно согласиться с вами там. Спасибо за то, что подчеркнули, что эти методы действительно имеют предназначенные функции.
 AnthonyW31 мая 2013 г., 00:13
Хотя производительность всегда является серьезной проблемой, принудительное выполнение контрактов избавляет меня от необходимости писать больше тестов в долгосрочной перспективе. Спасибо, что обратили меня на этот маленький самородок.

compareTo может привлечь гораздо больше работы, чем необходимо, чтобы получить ответ на равенство, котороеможет в конечном итоге проблема производительности зависит от использования вашего приложения.

Кроме этого, послеDRY Принципы было бы неплохо повторно использовать код, как вы предложили.

 OrangeDog29 мая 2013 г., 18:21
@AnthonyW Мне было интересно, почему ты говоришь о них ...
 AnthonyW29 мая 2013 г., 17:51
Хорошая заметка о потенциальной производительности. Несмотря на все мои шумихи по поводу NPE, я упустил из виду, что мой предложенный код уже правильно обрабатывает их, предполагая, что они выполнены правильно в сравнении. Единственная оставшаяся проблема - производительность.

Ваш ответ на вопрос