Коллекции, на основе которых нередко создаются потоки, уже имеют специальные методы для сортировки содержимого. Однако класс Stream также включает возможность сортировки. Такую сортировку мы можем задействовать, когда у нас идет набор промежуточных операций с потоком, которые создают новые наборы данных, и нам надо эти наборы отсортировать.
Для простой сортировки по возрастанию применяется метод sorted():
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Program { public static void main(String[] args) { List<String> phones = new ArrayList<String>(); Collections.addAll(phones, "iPhone X", "Nokia 9", "Huawei Nexus 6P", "Samsung Galaxy S8", "LG G6", "Xiaomi MI6", "ASUS Zenfone 3", "Sony Xperia Z5", "Meizu Pro 6", "Pixel 2"); phones.stream() .filter(p->p.length()<12) .sorted() // сортировка по возрастанию .forEach(s->System.out.println(s)); } }
Консольный вывод после сортировки объектов:
LG G6 Meizu Pro 6 Nokia 9 Pixel 2 Xiaomi MI6 iPhone X
Однако данный метод не всегда подходит. Уже по консольному выводу мы видим, что метод сортирует объекты по возрастанию, но при этом заглавные и строчные буквы рассматриваются отдельно.
Кроме того, данный метод подходит только для сортировки тех объектов, которые реализуют интерфейс Comparable.
Если же у нас классы объектов не реализуют этот интерфейс или мы хотим создать какую-то свою логику сортировки, то мы можем использовать другую версию метода
sorted()
, которая в качестве параметра принимает компаратор.
Например, пусть у нас есть следующий класс Phone:
class Phone{ private String name; private String company; private int price; public Phone(String name, String comp, int price){ this.name=name; this.company=comp; this.price = price; } public String getName() { return name; } public int getPrice() { return price; } public String getCompany() { return company; } }
Отсортируем поток обектов Phone:
import java.util.Comparator; import java.util.stream.Stream; public class Program { public static void main(String[] args) { Stream<Phone> phoneStream = Stream.of(new Phone("iPhone X", "Apple", 600), new Phone("Pixel 2", "Google", 500), new Phone("iPhone 8", "Apple",450), new Phone("Nokia 9", "HMD Global",150), new Phone("Galaxy S9", "Samsung", 300)); phoneStream.sorted(new PhoneComparator()) .forEach(p->System.out.printf("%s (%s) - %d \n", p.getName(), p.getCompany(), p.getPrice())); } } class PhoneComparator implements Comparator<Phone>{ public int compare(Phone a, Phone b){ return a.getName().toUpperCase().compareTo(b.getName().toUpperCase()); } }
Здесь определен класс компаратора PhoneComparator, который сортирует объекты по полю name. В итоге мы получим следующий вывод:
Galaxy S9 (Samsung) - 300 iPhone 8 (Apple) - 450 iPhone X (Apple) - 600 Nokia 9 (HMD Global) - 150 Pixel 2 (Google) - 500