Прежде всего, если вы используете Java 5 или выше, вы должны реализовать Comparable<MyClass>
вместо простого старого Comparable
, поэтому ваш метод compareTo
должен принимать параметры типа MyClass
, а не Object
:
public int compareTo(MyClass other) {
if (this == other) {
return 0;
} else {
int c = foo.CompareTo(other.foo)
if (c == 0) {
// what here?
} else {
return c;
}
}
}
На ваш вопрос Джош Блох в «Эффективной Java» (глава 3, пункт 12) говорит:
Разработчик должен обеспечить sgn (x.compareTo (y)) == -sgn (y.compare-
К (х)) для всех х и у. (Это подразумевает, что x.compareTo (y) должен выдать исключение
тогда и только тогда, когда y.compareTo (x) выдает исключение.)
Это означает, что если c == 0 в приведенном выше коде, вы должны вернуть 0.
Это, в свою очередь, означает, что у вас могут быть объекты A и B, которые не равны, но их сравнение возвращает 0. Что мистер Блох должен сказать по этому поводу?
Настоятельно рекомендуется, но не обязательно, чтобы (x.compareTo (y)
== 0) == (x.equals (y)). Вообще говоря, любой класс, который реализует
Сопоставимый интерфейс и нарушающий это условие должен четко указывать
этот факт. Рекомендуемый язык: «Примечание.
порядок, несовместимый с равными. ”
И
Класс, метод CompareTo которого накладывает порядок
что не согласуется с равенством будет по-прежнему работать, но отсортированные коллекции, содержащие
элементы класса могут не подчиняться генеральному контракту соответствующей коллекции
интерфейсы (Коллекция, Набор или Карта). Это потому что генеральные контракты
для этих интерфейсов определены с точки зрения метода equals, но отсортированные коллекции
используйте тест на равенство, наложенный CompareTo вместо равных. Это не
катастрофа, если это произойдет, но об этом нужно знать.
Обновление: Так что ИМХО с вашим текущим классом вы не можете сделать compareTo
совместимым с equals
. Если вам действительно нужно это иметь, единственный способ, которым я вижу, - это ввести нового члена, который бы дал строгий естественный порядок вашему классу. Тогда в случае, если все значащие поля двух объектов сравниваются с 0, вы все равно можете определить порядок двух на основе их значений специального порядка.
Этот дополнительный член может быть счетчиком экземпляров или отметкой времени создания. Или вы можете попробовать использовать UUID .