Использование equals() в compareTo()?

Тестовый код (просто для соответствия SSCCE, очевидно, есть гораздо лучшие способы раскачивать собственные модели данных без учета регистра)

public class TestClass implements java.lang.Comparable<TestClass> {

    public String test;

    @Override
    public int compareTo(TestClass o) {
        if (o == null) {
            throw new NullPointerException();
        }
        return equals(o) ? 0 : test.toLowerCase().compareTo(o.test.toLowerCase());
    }

    @Override
    public boolean equals(Object o) {
        return (o == this) ? true : o instanceof TestClass ? test.equalsIgnoreCase(((TestClass) o).test) : false;
    }

    @Override
    public int hashCode() {
        return test.toLowerCase().hashCode();
    }
}

Скажем, я хочу, чтобы мой класс, реализующий Comparable, следовал «настоятельным рекомендациям» предложено в API:

Настоятельно рекомендуется, но не обязательно, чтобы (x.compareTo(y)==0) == (x.equals(y)).

Было бы нормально использовать equals() внутри compareTo()? Конечно, мы гарантируем, что equals() не будет звонить compareTo() в ответ.

Аналогично: когда что включать?


person h.j.k.    schedule 06.09.2013    source источник
comment
Я спрашиваю об использовании equals() в compareTo(), а не для обсуждения того, когда использовать equals() или compareTo(). ;) Я также не вникаю в реализацию equals() и и compareTo() в классе String, что здесь выходит за рамки. Тестовый код на самом деле предназначен только для визуализации того, как equals() может использоваться внутри compareTo().   -  person h.j.k.    schedule 06.09.2013
comment
Это нормально, но, кстати: не пишите такие вещи, как a? true: b? c: false. Это запутанное выражение для a || b && c. То есть return o==this || o instanceof TestClass && test.equalsIgnoreCase(((TestClass) o).test) сделает то же самое.   -  person Holger    schedule 06.09.2013
comment
Спасибо, что заметили это! :) Я знал, что что-то не так, когда вводил true/false... Отличный улов.   -  person h.j.k.    schedule 06.09.2013


Ответы (1)


Все должно быть в порядке, если вы выполняете проверку NPE перед вызовом equals() внутри compareTo().

Прежде чем делать

test.toLowerCase().compareTo(o.test.toLowerCase());

вы также должны проверить, является ли тест NULL, потому что "someString".compareTo((String)null) вызовет исключение NullPointerException.

person Aniket Thakur    schedule 06.09.2013
comment
Спасибо, что заметили это! :) - person h.j.k.; 06.09.2013