Codectionary / Developer documentation / Java

Stream Terminal Operations

Terminal operations are what actually trigger a stream pipeline to execute and produce a final result, consuming the stream in the process - after a terminal operation runs, the stream cannot be reused. Common terminal operations include reduce() for combining elements into a single value, count(), sum-style operations for numeric streams, anyMatch()/allMatch() for boolean checks, and findFirst() for retrieving a single element.

Syntax

stream.reduce(identity, accumulator)

Examples

reduce(): Combining Elements

Reducing a stream down to a single accumulated value.

import java.util.List;

List<Integer> numbers = List.of(1, 2, 3, 4, 5);

int sum = numbers.stream()
    .reduce(0, (a, b) -> a + b);

System.out.println(sum);  // 15

int product = numbers.stream()
    .reduce(1, (a, b) -> a * b);
System.out.println(product);  // 120

count(), anyMatch(), allMatch()

Common checks that return a single boolean or number.

import java.util.List;

List<Integer> numbers = List.of(2, 4, 6, 8, 10);

long count = numbers.stream().filter(n -> n > 5).count();
System.out.println(count);  // 3

boolean allEven = numbers.stream().allMatch(n -> n % 2 == 0);
System.out.println(allEven);  // true

boolean anyOverTen = numbers.stream().anyMatch(n -> n > 10);
System.out.println(anyOverTen);  // false

Numeric Streams: sum, average, max

IntStream and its relatives provide direct numeric aggregation methods.

import java.util.List;

List<Integer> scores = List.of(85, 92, 78, 90, 88);

int total = scores.stream().mapToInt(Integer::intValue).sum();
System.out.println(total);  // 433

double average = scores.stream().mapToInt(Integer::intValue).average().orElse(0);
System.out.println(average);  // 86.6

int highest = scores.stream().mapToInt(Integer::intValue).max().orElse(0);
System.out.println(highest);  // 92

findFirst() and findAny()

Retrieving a single matching element from a stream, wrapped in an Optional.

import java.util.List;
import java.util.Optional;

List<String> names = List.of("John", "Zain", "Jamal", "Zoe");

Optional<String> firstZ = names.stream()
    .filter(name -> name.startsWith("Z"))
    .findFirst();

firstZ.ifPresent(name -> System.out.println("Found: " + name));  // Found: Zain

Best practices

  • Use reduce() for custom aggregation logic, but prefer built-in terminal operations (sum(), count(), max()) when they already do what you need
  • Use anyMatch()/allMatch()/noneMatch() instead of manually looping and setting a boolean flag - they short-circuit and stop as soon as the result is known
  • Use mapToInt()/mapToDouble() to switch to a primitive numeric stream before calling sum()/average(), since those are not available on a generic Stream<Integer>
  • Handle the Optional returned by findFirst(), max(), and similar methods explicitly - never assume a matching element exists

Runtime & versions

Java Virtual Machine. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

Java Language Specification

Specifications & further reading