Ответ
Терминальные операции завершают поток и возвращают результат (не поток). Они "потребляют" поток.
Основные терминальные операции:
forEach(Consumer)— выполняет действие для каждого элемента. Порядок не гарантирован в параллельных потоках.forEachOrdered(Consumer)— выполняет действие с сохранением порядка, даже в параллельных потоках.collect(Collector)— собирает элементы в коллекцию или другой объект. Самый гибкий метод.List<String> list = stream.collect(Collectors.toList()); Map<String, Integer> map = stream.collect(Collectors.toMap(k -> k, v -> v.length()));toArray()— возвращает массив элементов потока.reduce(...)— сводит элементы к одному значению (аккумулятор).Optional<Integer> sum = numbers.stream().reduce((a, b) -> a + b);min(Comparator)/max(Comparator)— возвращают минимальный/максимальный элемент (Optional).count()— возвращает количество элементов в потоке (long).anyMatch(Predicate)/allMatch(Predicate)/noneMatch(Predicate)— проверяют, соответствует ли поток условию (хотя бы один, все, ни один). Возвращаютboolean.findFirst()/findAny()— возвращают первый/любой элемент потока (Optional).findAny()эффективнее в параллельных потоках.
Пример:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean hasEven = numbers.stream().anyMatch(n -> n % 2 == 0); // true
long count = numbers.stream().filter(n -> n > 2).count(); // 3
Optional<Integer> first = numbers.stream().findFirst(); // Optional[1]