Обратная сортировка потока файлов через lambda в Java 8
Быстрый ответ
Для сортировки потока элементов в обратном порядке воспользуйтесь методом sorted()
в сочетании с Comparator.reverseOrder()
:
List<String> descList = list.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
Если требуется отсортировать объекты пользовательского типа или сортировать по определенному полю, используйте Comparator.comparing()
:
List<CustomType> descList = list.stream()
.sorted(Comparator.comparing(CustomType::getField).reversed())
.collect(Collectors.toList());
Если нужно отсортировать список файлов по дате последнего изменения, воспользуйтесь таким подходом:
List<File> sortedFiles = files.stream()
.sorted(Comparator.comparing(File::lastModified).reversed())
.collect(Collectors.toList());
Такой подход позволит переместить более ранние значения в конец списка, так как reversed()
инвертирует порядок сортировки.
От лямбда-выражений до ссылок на методы
Писать код, используя ссылки на методы вместо лямбда-выражений, более наглядно и при этом упрощает поддержку кода:
list.stream()
.sorted(Comparator.comparing(MyClass::getValue).reversed())
.forEach(System.out::println);
Здесь MyClass::getValue
— это метод, значение которого используется для сортировки, а reversed()
переворачивает порядок сортировки.
Изменение потока данных после сортировки
Вы можете выполнить дополнительные действия с отсортированным потоком данных следующим образом:
- Фильтрация
list.stream()
.sorted(Comparator.comparing(String::length).reversed())
.filter(s -> s.startsWith("A"))
.collect(Collectors.toList());
- Пропуск и ограничение
list.stream()
.sorted(Comparator.comparingInt(String::length).reversed())
.skip(2)
.limit(5)
.collect(Collectors.toList());
- Если требуется удалить элементы, сначала нужно получить результаты сортировки, а затем уже изменять собранные данные, чтобы не нарушать свойство неизменяемости потоков.
Сценарии сортировки, с которыми вы столкнетесь
Сложные сценарии сортировки встречаются довольно часто. Вот некоторые из них:
- Сортировка по значениям вложенных атрибутов:
list.stream()
.sorted(Comparator.comparing((CustomType t) -> t.getNestedType().getNestedField()).reversed())
.collect(Collectors.toList());
- Сортировка по нескольким полям:
list.stream()
.sorted(Comparator.comparing(CustomType::getPrimaryField)
.thenComparing(CustomType::getSecondaryField).reversed())
.collect(Collectors.toList());
- Обработка null-значений:
list.stream()
.sorted(Comparator.comparing(CustomType::getField, Comparator.nullsLast(Comparator.naturalOrder())).reversed())
.collect(Collectors.toList());
- Создание собственного компаратора для реализации особой логики сравнения:
list.stream()
.sorted((o1, o2) -> {
// здесь сложная логика
return o2.compareTo(o1);
})
.collect(Collectors.toList());
Визуализация
Визуализируем процесс обратной сортировки на примере гонки автомобилей:
Обычный финиш: [4-е место 🚗, 3-е место 🛺, 2-е место 🏎, 1-е место 🚀] /// Первые приходят последними.
Применение Comparator.comparing().reversed()
позволяет самым быстрым ускориться.
Обратная сортировка с использованием lambda: [1-е место 🚀, 2-е место 🏎, 3-е место 🛺, 4-е место 🚗]
Таким образом, лямбда-выражения в Java 8 меняют направление гонки на противоположное:
stream.sorted(Comparator.comparing(T::getSpeed).reversed())
// Самый быстрый оставил все за собой!
При работе со значениями, такими как временные метки, используйте методы Comparator
, вместо умножения на -1
:
list.stream()
.sorted(Comparator.comparingLong(T::getTimestamp).reversed())
.collect(Collectors.toList());
Отсортированные результаты можно собрать в коллекцию по своему выбору — список, множество, карту и т.д.
Полезные материалы
- Stream (Java Platform SE 8) — официальная документация API Java 8 для интерфейса Stream.
- Java 8 stream reverse order – Stack Overflow — вопросы и ответы, касающиеся сортировки потоков в обратном порядке.
- Туториал по Java 8 Stream – winterbe — детальное руководство по использованию потоков в Java 8 с примерами.
- Однострочники в Java 8 с помощью лямбд — примеры эффективного использования лямбда-выражений в Java 8 для написания компактного кода.