Вы нарушаете договор метода сравнения, ваши отношения не являются переходными. "Разработчик должен убедиться, что sgn(compare(x, y)) == -sgn(compare(y, x))
для всех x
и y
"
Учитывайте следующее:
public static void main(String[] args){
Recipient r1; // with isDateLastContactNull() == true;
Recipient r2; // with isDateLastContactNull() == false;
RecipientComparator rc = new RecipientComparator();
System.out.println(rc.compare(r1, r2)); // -1
System.out.println(rc.compare(r2, r1)); // -1
// both print -1 which is not transitive.
}
Причина заключается в этом коде:
if (o1.isDateLastContactNull() && o2.isDateLastContactNull()) {
// if both null, return comparison of addresses
return o1.getAddress().compareTo(o2.getAddress());
} else if (o1.isDateLastContactNull()) {
// if first null, return -1
return -1;
} else if (o2.isDateLastContactNull()) {
// if second null, also return -1 ?
return -1; // should probably be 1 instead
}
Возможно, вам следует вернуть 1
для второго условия.
Контракт такой, как здесь определен:
int compare(T o1, T o2):
Сравнивает два аргумента для порядка.Возвращает отрицательное целое число, ноль или положительное целое число, так как первый аргумент меньше, равен или больше второго.В вышеприведенном описании обозначение sgn(expression)
обозначает математическую функцию signum, которая определена для возврата одного из -1
, 0
или 1
в зависимости от того, является ли значение выражения отрицательным, нулевым или положительным.
Разработчик должен убедиться, что sgn(compare(x, y)) == -sgn(compare(y, x))
для всех x
и y
.(Это означает, что compare(x, y)
должно выдавать исключение тогда и только тогда, когда compare(y, x)
выдает исключение.)
Разработчик также должен обеспечить транзитивность отношения: ((compare(x, y) > 0) && (compare(y, z) > 0))
подразумевает compare(x, z) > 0
.
Наконец, разработчик должен убедиться, что compare(x, y) == 0
подразумевает, что sgn(compare(x, z)) == sgn(compare(y, z))
для всех z
.
Обычно это так, но строго не требуется, чтобы (compare(x, y) == 0) == (x.equals(y))
.Вообще говоря, любой компаратор, который нарушает это условие, должен четко указывать этот факт.Рекомендованный язык: «Примечание: этот компаратор устанавливает порядок, не совместимый с равным».