#java #logic #comparator
#java #Логические #компаратор
Вопрос:
У меня есть пользовательская таблица, использующая компаратор для сортировки элементов по столбцам. Я хочу «закрепить» определенные элементы вверху, независимо от текущей сортировки (asc / desc). Помимо «обычных» элементов (C), которые сравниваются как обычно, у меня также есть один специальный элемент (A), который всегда должен быть в верхней части таблицы, и N «избранных» элементов (B), которые должны быть после A и перед C, и их порядок не важен (но я также попытался «отсортировать» их на основе их числового значения).
Вот представление о том, как должна выглядеть моя таблица, независимо от текущей сортировки (когда-либо должны сортироваться только элементы C):
A (always present on top)
B (isFavorite)
B (isFavorite)
C (these items are sorted normally)
C
...
C
Вот мой компаратор, который не работает должным образом. Иногда A идет после B или я даже получаю Comparator violates general contract
исключение.
private class CustomOrderAwareComparator implements Comparator<MyObject> {
@Override
public int compare(MyObject o1, MyObject o2) {
// isA() is always true only for one item
if(o1.isA() amp;amp; o2.isA())
return 0;
else if(o1.isA())
return table.getSortedOrder() == DESCENDING ? 1 : -1;
// isB() can be true for multiple items
if(o1.isB() amp;amp; o2.isB()))
return 0;
else if(o1.isB())
return table.getSortedOrder() == DESCENDING ? 1 : -1;
return o1.getValue().compareTo(o2.getValue());
}
}
Я был бы признателен за любую информацию о том, чего мне здесь не хватает. Спасибо!
Комментарии:
1. это то, что отсутствует
else if
условие дляo2.isA()
2. что такое
e2
ошибка копирования и вставки? и что более важно, что произойдет, еслиo2
этоA
? илиB
? (для упорядочивания, когда обаA
(илиB
) просто возвращают результат изcompareTo
вместо нуля)3. @CarlosHeuberger да, я исправил пример. A гарантированно будет только одним. В любом наборе элементов всегда будет только один A.
4. не отвечает «что, если
o2
естьA
?» — вы не тестируете случай, когдаo2
(только) это одинA
элемент, вы только проверяетеo1
— вам нужно что-то вродеif (o2,isA()) return ...
{то же самое дляif (o2.isB()) ...
}5. @CarlosHeuberger спасибо, это помогло! Я добавил эти проверки, и теперь это работает.
Ответ №1:
Я думаю, что после else if (o1.isA()) return...
вам также нужно else if (o2.isA()) return table.getSortedOrder() == DESCENDING ? -1 : 1;
. Сделайте то же самое для B
. В противном случае некоторые из As и некоторые из Bs могут не пройти getValue()
проверку.
Это может исправить общее нарушение контракта, но вам может потребоваться обновить ваш equals
метод, чтобы соответствовать поведению compare
.
Комментарии:
1. на самом деле
else
не требуется, посколькуreturn
вводится в каждыйif
блок2. Да, добавление этих двух
else if
помогло и теперь работает должным образом. Спасибо! Не уверен, следует ли все еще переопределятьequals
сейчас, поскольку все уже работает? Какой случай это разрешило бы?3. Прохладный. Ошибка контракта, вероятно, произошла, когда коллекция, использующая компаратор для сортировки, заметила, что метод equals не соответствует методу compare. Типичный метод equals, сгенерированный IDE, скорее всего, соответствует вашему фиксированному методу сравнения.