Для чего используется метод collect() в Java Stream API?

«Для чего используется метод collect() в Java Stream API?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Метод collect() — это терминальная операция в Stream API, которая преобразует элементы потока в другую, обычно мутабельную, структуру данных (коллекцию, строку, мапу) или агрегированный результат.

Основная идея: collect() принимает объект Collector, который описывает стратегию накопления элементов.

Практические примеры с использованием Collectors:

  1. Сбор в стандартные коллекции:
    List<String> list = stream.collect(Collectors.toList());
    Set<Integer> set = stream.collect(Collectors.toSet());
  2. Сбор в конкретную реализацию коллекции:
    LinkedList<String> linkedList = stream.collect(Collectors.toCollection(LinkedList::new));
  3. Объединение строк:
    String joined = stream.collect(Collectors.joining(", ", "[", "]")); // [A, B, C]
  4. Группировка и агрегация:

    // Группировка по длине строки
    Map<Integer, List<String>> byLength = stream.collect(Collectors.groupingBy(String::length));
    
    // Подсчет количества элементов в каждой группе
    Map<String, Long> countByCity = people.stream()
        .collect(Collectors.groupingBy(Person::getCity, Collectors.counting()));
  5. Сведение к одному значению (агрегация):
    Double average = stream.collect(Collectors.averagingInt(String::length));
    IntSummaryStatistics stats = stream.collect(Collectors.summarizingInt(String::length));

Почему collect, а не toList()? Метод collect() является универсальным. Статические методы типа Stream.toList() (появился в Java 16) возвращают неизменяемый список и подходят для простых случаев, в то время как collect(Collectors.toList()) дает больше контроля (например, можно указать конкретную реализацию списка).