Collectors

Базовый Java
≈ 2 мин чтения

Collector описывает, как собрать результат

Stream.toList() отлично подходит, когда нужен обычный список. Но иногда элементы нужно объединить в строку, сгруппировать по признаку или превратить в Map. Для таких задач используется терминальная операция collect() вместе с готовыми collector-ами из класса Collectors.

joining объединяет строки

String result = Stream.of("Java", "Spring", "SQL")
        .collect(Collectors.joining(", "));

В result будет строка Java, Spring, SQL. У joining также есть варианты с префиксом и суффиксом, если нужно сразу получить оформленную строку.

groupingBy собирает элементы по ключу

groupingBy вычисляет ключ для каждого элемента и помещает элементы с одинаковым ключом в одну группу.

Map<Integer, List<String>> byLength =
        Stream.of("Java", "SQL", "Spring", "HTTP")
                .collect(Collectors.groupingBy(String::length));

Ключом здесь становится длина строки. В результате строки длины 4 окажутся в одной группе, длины 3 — в другой и так далее. Похожая операция partitioningBy делит элементы ровно на две группы по результату Predicate.

toMap строит отображение

Map<String, Integer> lengths =
        Stream.of("Java", "Spring", "SQL")
                .collect(Collectors.toMap(
                        word -> word,
                        String::length
                ));

Первое правило создаёт ключ, второе — значение. Если два элемента дадут одинаковый ключ, простой вариант toMap не сможет выбрать победителя и выбросит исключение. Для таких данных нужно заранее определить функцию объединения значений.

Map<Integer, String> oneWordByLength =
        Stream.of("Java", "HTTP", "Spring")
                .collect(Collectors.toMap(
                        String::length,
                        word -> word,
                        (left, right) -> left
                ));
Stream.toList() и Collectors.toList() — не полные аналоги. Stream.toList() возвращает неизменяемый список. У Collectors.toList() нет гарантии конкретной реализации и изменяемости результата. Если нужна определённая коллекция, лучше выразить это явно.