JAVAARCHIVEBOOKS Telegram 233
Как написать компаратор

Компаратор задаёт правило сравнения элементов между собой. Делает он это с помощью метода 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. Используются для полей примитивного типа, чтобы избежать лишнего боксинга. Если в классе Order

Long 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()
👍3😁1



tgoop.com/javaarchivebooks/233
Create:
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. Используются для полей примитивного типа, чтобы избежать лишнего боксинга. Если в классе Order

Long 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

View MORE
Open in Telegram


Telegram News

Date: |

The court said the defendant had also incited people to commit public nuisance, with messages calling on them to take part in rallies and demonstrations including at Hong Kong International Airport, to block roads and to paralyse the public transportation system. Various forms of protest promoted on the messaging platform included general strikes, lunchtime protests and silent sit-ins. The optimal dimension of the avatar on Telegram is 512px by 512px, and it’s recommended to use PNG format to deliver an unpixelated avatar. 1What is Telegram Channels? The best encrypted messaging apps Telegram channels fall into two types:
from us


Telegram Уютное сообщество джавистов
FROM American