tgoop.com/javaarchivebooks/233
Create:
Last Update:
Last Update:
Как написать компаратор
Компаратор задаёт правило сравнения элементов между собой. Делает он это с помощью метода compare
:
public int compare(T o1, T o2) {…}Если метод вернул
▫️ число больше нуля — первый элемент больше второго
▫️ 0 — элементы равны
▫️ число меньше нуля — первый меньше второго
Простейшая и популярная реализация — вычесть одно значение из другого:
(o1, o2) -> (int) (o1.getSum() - o2.getSum())❓ Что с этим не так?
Я всегда сомневаюсь, что из чего вычитать. Если вы отвечали на опрос дольше одной секунды, значит мы в одном лагере:) Компаратор — совсем не то место, где мозг должен спотыкаться.
В Java 8 в интерфейсе
Comparator
появился удобный метод:orders.sort(comparing(Order::getSum))Что классно:
✅ Не надо вспоминать, что из чего вычитать
✅ Легко сделать сравнение в обратном порядке:
comparing(Order::getSum).reversed()✅ Можно учесть null:
nullsFirst(comparing(Order::getSum))✅ Удобно сортировать по нескольким полям:
nullLast(…)
comparing(Order::getSum).thenComparing(Order::getId)Самостоятельно обрабатывать null и писать сложные сортировки очень утомительно. Помню, как с удовольствием удаляла из проекта компараторы на 20 строк после перехода на Java 8😊
Важные нюансы:
1️⃣ comparing*
В интерфейсе
Comparator
также доступны методы comparingInt
, comparingLong
и comparingDouble
. Используются для полей примитивного типа, чтобы избежать лишнего боксинга. Если в классе OrderLong id
→ используем comparing(Order::getId)
long id
→ comparingLong(Order::getId)
Не указывайте тип лишний раз. Для работы с объектами подойдёт обычный comparing
2️⃣ Нетривиальная работа с null*
В обычных методах легко понять, что происходит: comparing(A).reversed().thenComparing(Б)=
отсортировать по полю А в обратном порядке, дубликаты отсортировать по Б
Методы
null*
выбиваются из этой схемы.nullsFirst(comparing(Order::getSum))означает, что первыми будут null объекты, а существующие заказы отсортируются по сумме. Этот компаратор работает для такого кода:
orders.add(null);
// эти элементы будут впередиorders.add(new Order(…));
// эти отсортируются по полю sum Если в списке нет null объектов, но в поле sum возможен null, придётся писать так:
…comparing(Order::getSum, nullsFirst(naturalOrder()));Сравнение по нескольким nullable полям выглядит совсем плохо. К счастью, на практике такие задачи встречаются редко.
Ответ на вопрос перед постом:
(o1, o2) -> (int) (o2.getSum() - o1.getSum())Но лучше использовать
comparing(Order::getSum).reversed()
✨BY Уютное сообщество джавистов
Share with your friend now:
tgoop.com/javaarchivebooks/233