Как перевернуть сортировку компаратора в Java 8: примеры

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для изменения направления сортировки используйте метод Comparator.reversed().

Java
Скопировать код
Comparator<String> reverseComparator = Comparator.<String>naturalOrder().reversed();

Всё готово! Строки будут отсортированы в обратном лексикографическом порядке. Никаких дополнительных действий не потребуется.

Кинга Идем в IT: пошаговый план для смены профессии

Stream API: упрощение сортировки в обратном порядке

С применением Streams и Comparator в Java 8 обратная сортировка становится значительно проще.

Java
Скопировать код
List<String> words = Arrays.asList("B", "A", "C");
List<String> descendingList = words.stream()
    .sorted(Comparator.reverseOrder())
    .collect(Collectors.toList());
// Приятно порадовать вас алфавитом, представленным задом наперёд.

Благодаря этому вам не придётся читать алфавит задом наперёд.

Работа с сложными типами данных: цепочки Comparator'ов к вашим услугам

В случае необходимости создать цепочку Comparator'ов для выполнения более сложных задач сортировки.

Java
Скопировать код
List<Person> people = getPeople();
Comparator<Person> sortByAgeThenByName = Comparator
    .comparing(Person::getAge)
    .reversed()
    .thenComparing(Person::getName);
// Обеспечим приоритезацию по старшинству, а затем упорядочим имена в алфавитном порядке. Это справедливо.

Collections.sort(people, sortByAgeThenByName);

Теперь список людей отсортирован вначале по возрасту (начиная с старшего), а затем по именам. Молодость, подожди! 👴

Настройка направления сортировки

Взгляды на сортировку бывают разные: в порядке убывания или возрастания.

Java
Скопировать код
int sortOrder = -1; // 1 для сортировки по возрастанию, -1 для сортировки по убыванию
Collections.sort(people, (p1, p2) -> sortOrder * p1.getAge().compareTo(p2.getAge()));
// Как бы нам хотелось так просто "перевернуть" возраст!

Значение переменной sortOrder (1 или -1) определяет направление сортировки. Мы выбираем точку зрения.

Работа со сложными типами данных

Стильная и эффективная сортировка сложных типов данных.

Java
Скопировать код
Comparator<CustomType> customComparator = Comparator.comparing(CustomType::getCustomField).reversed();
// Это сложнее, чем попытка сыграть в "тетрис" с завязанными глазами.
Collections.sort(listOfCustomType, customComparator);

Используя метод .reversed(), мы становимся мастерами сортировки.

Визуализация

Представьте себе стрелки, указывающие направление сортировки. Одна указывает вверх (⬆️ — для возрастания), другая вниз (⬇️ — для убывания).

Markdown
Скопировать код
До использования reverse: A ➡️ B ➡️ C (A < B, B < C)
Comparator:   ⬆️

Важно знакомство с методом .reversed() для изменения порядка сортировки!

Markdown
Скопировать код
После использования reverse:  C ➡️ B ➡️ A (C > B, B > A)
Comparator:     ⬇️

Всё ли понятно? Это не сложнее, чем приготовить омлет по рецепту, прочитанному задом наперёд 🥞.

Сортировка по множеству атрибутов: в гущу сложностей

Если у ваших данных множество атрибутов, как у человеческого характера, используйте thenComparing.

Java
Скопировать код
// Сначала сортируем по возрасту по возрастанию, затем по имени по убыванию
Comparator<Person> compositeComparator = Comparator
    .comparing(Person::getAge)
    .thenComparing(Comparator.comparing(Person::getName).reversed());

people.sort(compositeComparator);
// Это как сначала сравнивать возраст, а затем красоту, только всё наоборот.

Так мы изучаем иерархическую сортировку: сначала по возрасту (чем моложе, тем раньше), затем по имени в обратном порядке.

Динамическая сортировка во время выполнения с использованием условных операторов

Динамическая сортировка на лету? Не вопрос!

Java
Скопировать код
boolean reverseNames = someCondition;
Comparator<Person> conditionalComparator = Comparator
    .comparing(Person::getAge)
    .thenComparing(
        Person::getName,
        reverseNames ? Comparator.reverseOrder() : Comparator.naturalOrder()
    );

Collections.sort(people, conditionalComparator);

Порядок следования имен меняется в зависимости от значения переменной reverseNames. Такая сортировка обладает гибкостью.

Полезные материалы

  1. Comparator (Java Platform SE 8) — Официальное руководство по работе с Comparator в Java.
  2. Collections.reverseOrder() в Java с примерами – GeeksforGeeks — Как инвертировать порядок в Java.
  3. Учебник | DigitalOcean — Объяснение работы с Comparator в обратном порядке в Java.
  4. android – Сортировка списка с помощью ArrayAdapter – Stack Overflow — Решения специалистов в сфере сортировки данный при помощи Comparator'ов, взяты с Stack Overflow.
  5. Требуется проверка! | Cloudflare — Обзор возможностей сортировки списков с использованием Stream API Java 8.