если я назову эту строку кода
Arrays.sort(allNew, 0, sizeNew, mCatBPosComparator);
с этим компаратором
private class BPosComparator implements Comparator<CatBPos> {
private static final int SWAP_BPosS = 1;
@Override
public int compare(CatBPos p1, CatBPos p2) {
int lCompare;
if (TimeUtils.isNotVoid(p1.getHdopBPos().getTime()) && TimeUtils.isNotVoid(p2.getHdopBPos().getTime())) {
lCompare = p1.getHdopBPos().getTime().compareTo(p2.getHdopBPos().getTime());
if (lCompare != 0) {
return lCompare;
}
}
lCompare = p1.getBPos().getTime().compareTo(p2.getBPos().getTime());
if (lCompare != 0) {
return lCompare;
}
if (p1.getBPos().isDeparture() && p2.getBPos().isVacation()) {
return SWAP_BPOS;
} else if (p1.getBPos().isVacation() && p2.getBPos().isArrival()) {
return SWAP_BPOS;
}
// Ankunft und Abfahrt für denselben Bahnhof sollen in der richtigen Reihenfolge sein
if (p1.getBPos().isDeparture() && p2.getBPos().isArrival() && p1.getBPos().getStat().equals(p2.getBPos().getStat())) {
return SWAP_BPOS;
}
return 0;
}
}
Я сталкиваюсь с этим Исключением:
Comparison method violates its general contract!
Я вижу много вопросов по этому поводу. Но я этого не понимаю. Не могли бы вы помочь мне?
Я подозреваю, что это, по крайней мере, одна непосредственная проблема:
if (p1.getBPos().isDeparture() && p2.getBPos().isVacation()) {
return SWAP_BPOS;
} else if (p1.getBPos().isVacation() && p2.getBPos().isDeparture()) {
return SWAP_BPOS;
}
Если вы вызываете compare(p1, p2)
а затем compare(p2, p1)
вы получите тот же ненулевой результат... который нарушает правила сравнения.
В принципе, ваше сравнение должно подчиняться документированным правилам. Вышесказанное является одной из проблем - вполне возможно, что их больше. Вы должны внимательно прочитать правила и подумать о том, как должно работать ваше сравнение.
Вы можете начать с отрицания SWAP_BPOS
для обратной ситуации:
if (p1.getBPos().isDeparture() && p2.getBPos().isVacation()) {
return SWAP_BPOS;
} else if (p1.getBPos().isVacation() && p2.getBPos().isDeparture()) {
return -SWAP_BPOS;
}
Это может быть не все, что нужно, но это начало.
Вы должны убедиться, что ваш оператор сравнения подчиняется всем соответствующим математическим правилам:
В частности, обратите внимание на код, который может возвращать тот же порядок/результат для противоположных входов. Ваше сравнение должно быть в состоянии окончательно заказать ваши товары.
По моему опыту, ошибки в пункте 2 кажутся наиболее распространенной ошибкой.
Comparator.compareTo
, который соответствует этим правилам.
Оператор сравнения должен быть транзитивным. Короче говоря, это означает, что вы должны определить его таким образом, что если a.compareTo(b)
отрицательный, а b.compareTo(c)
отрицательный, то a.compareTo(c)
также является отрицательным. Это несколько интуитивно - если a меньше b и b меньше c, то a меньше c. Также вы должны убедиться, что если a.compareTo(b)
равно нулю, чем b.compareTo(a)
равно нулю, т.е. если a равно b, то b равно a.
sign(a.compareTo(b)) = -sign(b.compareTo(a))
- помните, a.compareTo(b)
должен давать противоположный порядок b.compareTo(a)
if a!=b
; это одна из самых распространенных ошибок при реализации.
В принципе, ваш метод сравнения должен быть последовательным. Если A> B и B> C, то A должно быть больше C. Вероятно, ваш код там не работает.
A > B
и B > C
, предполагается, что A > C
, а не наоборот.