Какие основные методы Stream API в Java?

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

Ответ

Stream API предоставляет два типа операций: промежуточные (возвращают новый Stream) и терминальные (завершают поток и возвращают результат).

Промежуточные операции:

  • filter(Predicate<T>) – отбирает элементы, удовлетворяющие условию.
  • map(Function<T, R>) – преобразует каждый элемент.
  • flatMap(Function<T, Stream<R>>) – преобразует элемент в поток и объединяет все потоки в один.
  • distinct() – удаляет дубликаты (использует equals()).
  • sorted() / sorted(Comparator<T>) – сортирует элементы.
  • peek(Consumer<T>) – выполняет действие для каждого элемента (часто для отладки).
  • limit(long n) – ограничивает поток первыми n элементами.
  • skip(long n) – пропускает первые n элементов.

Терминальные операции:

  • forEach(Consumer<T>) – выполняет действие для каждого элемента.
  • collect(Collector<T, A, R>) – собирает элементы в коллекцию или другую структуру.
  • reduce(BinaryOperator<T>) – выполняет свертку элементов (например, нахождение суммы).
  • count() – возвращает количество элементов.
  • min(Comparator<T>) / max(Comparator<T>) – находит минимальный/максимальный элемент.
  • anyMatch(Predicate<T>) / allMatch() / noneMatch() – проверяют, удовлетворяет ли поток условию.
  • findFirst() / findAny() – возвращают опциональный элемент потока.

Пример использования:

List<String> result = names.stream()
    .filter(name -> name.length() > 3)  // Промежуточная
    .map(String::toUpperCase)           // Промежуточная
    .sorted()                           // Промежуточная
    .collect(Collectors.toList());      // Терминальная

Почему это важно: Промежуточные операции «ленивы» – вычисления происходят только при вызове терминальной операции, что оптимизирует обработку данных.