Terminal Operations

A terminal operation starts the Stream and returns a result that depends on the Stream pipeline and content.For example, collect is a terminal operation because additional operation cannot be added to a Stream pipeline after collect has been called.

In the examples below, many of the lambdas could be replaced by method references (e.g. the lambda () → new StringBuilder can be replaced by a method reference StringBuilder::new).

Common Operations

The following terminal operations are accepted by a Stream:

Operation Parameter(s) Action

forEach

Consumer

Performs the given Consumer action for each element in the stream in any order

forEachOrdered

Consumer

Performs the given Consumer action for each element in the stream in stream order

collect

Collector

Returns a reduction of the elements in the stream. For example a List, Set or a Map

min

Comparator

Returns the smallest element (as determined by the provided Comparator) in the stream (if any)

max

Comparator

Returns the biggest element (as determined by the provided Comparator) in the stream (if any)

count

-

Returns the number of elements in the stream

anyMatch

Predicate

Returns whether at least one element in this stream matches the provided Predicate

allMatch

Predicate

Returns whether all elements in this stream match the provided Predicate

noneMatch

Predicate

Returns whether no elements in this stream match the provided Predicate

findFirst

-

Returns the first element in this stream (if any)

findAny

-

Returns any element in this stream (if any)

toArray

-

Returns an array containing all the elements in this stream

toArray

IntFunction

Returns an array containing all the elements in this stream whereby the array is created using the provided IntFunction

forEach

     Stream.of("B", "A", "C" , "B")
        .forEach(System.out::print);

might output "CBBA". However, there is no guarantee of a particular order using forEach. Despite this, most Stream implementations actually would output "BACB".

forEachOrdered

     Stream.of("B", "A", "C" , "B")
        .forEachOrdered(System.out::print);

always outputs "BACB" (as opposed to forEach).

collect

     Stream.of("B", "A", "C" , "B")
        .collect(Collectors.toList());

returns a List<String> equal to ["B", "A", "C", "B"]

     Stream.of("B", "A", "C" , "B")
        .collect(Collectors.toSet());

returns a Set<String> equal to ["A", "B", "C"]

    Stream.of("I", "am", "a", "stream")
        .collect(Collectors.toMap(
            s -> s.toLowerCase(), // Key extractor
            s -> s.length())      // Value extractor
        )

returns a Map<String, Integer> equal to {a=1, stream=6, i=1, am=2}. Thus, the Map contains a mapping from a word (key) to how many characters that word has (value).

min

     Stream.of("B", "A", "C" , "B")
        .min(String::compareTo);

returns Optional[A] because "A" is the smallest element in the stream.

    Stream.<String>empty()
        .min(String::compareTo);

returns Optional.empty because there is no min value because the stream is empty.

max

     Stream.of("B", "A", "C" , "B")
        .max(String::compareTo);

returns Optional[C] because "C" is the largest element in the stream.

    Stream.<String>empty()
        .max(String::compareTo);

returns Optional.empty because there is no max value because the stream is empty.

count

----a
     Stream.of("B", "A", "C" , "B")
        .count();
----
returns 4 because there are four elements in the stream.
----a
    Stream.empty()
        .count();
----
returns 0 because there are no elements in an empty stream.

anyMatch

    Stream.of("B", "A", "C", "B")
        .anyMatch("A"::equals);

returns true because there is an "A" element in the stream.

    Stream.of("B", "A", "C", "B")
        .anyMatch("Z"::equals);

returns false because there are no "Z" elements in the stream.

noneMatch

    Stream.of("B", "A", "C", "B")
        .noneMatch("A"::equals);

returns false because there is an "A" element in the stream.

    Stream.of("B", "A", "C", "B")
        .noneMatch("Z"::equals);

returns true because there are no "Z" elements in the stream.

findFirst

    Stream.of("B", "A", "C", "B")
        .findFirst();

returns Optional[B] because "B" is the first element in the stream.

    Stream.<String>empty()
        .findFirst();

returns Optional.empty because the stream is empty.

findAny

    Stream.of("B", "A", "C", "B")
        .findAny();

might return Optional[C] or any other element in the stream.

    Stream.<String>empty()
        .findAny();

returns Optional.empty because the stream is empty.

toArray

    Stream.of("B", "A", "C", "B")
        .toArray();

Returns an array containing [B, A, C, B] created automatically by the toArray operator.

    Stream.of("B", "A", "C", "B")
        .toArray(String[]::new)

Returns an array containing [B, A, C, B] that will be created by the provided constructor, for example using the equivalent to new String[4].

Less Common Operations

Here is a list of other terminal operations that are a bit less commonly used by at least some programmers:

Operation Parameter(s) Action

collect

Supplier, BiConsumer, BiConsumer

Returns a reduction of the elements in the stream starting with an empty reduction (e.g. an empty List) obtained from the Supplier and then applying the first BiConsumer for each element and at the end, combining using the second BiConsumer

reduce

T, BinaryOperation

Using a first T and then subsequently applying a BinaryOperation for each element in the stream, returns the value of the last value (reduction)

reduce

BinaryOperation

By subsequently applying a BinaryOperation for each element in the stream, returns the value of the last value (reduction)

reduce

T, BiFunction, BinaryOperator

In parallel, using first values T and then subsequently applying a BiFunction for each element in the stream, returns the value of the last values combined using the combining BinaryOperator

iterator

-

Returns an Iterator of all the values in this stream

spliterator

-

Returns a Spliterator with all the values in this stream

collect with 3 Parameters

            Stream.of("B", "A", "C", "B")
                                .collect(
                    () -> new StringBuilder(),
                    (sb0, sb1) -> sb0.append(sb1),
                    (sb0, sb1) -> sb0.append(sb1)
                )

returns a StringBuilder containing "BACB" that will be created by the provided supplier and then built up by the append-lambdas.

reduce

    Stream.of(1, 2, 3, 4)
        .reduce((a, b) -> a + b)

returns the value of Optional[10] because 10 is the sum of all Integer elements in the Stream. If the Stream is empty, Optional.empty() is returned.

    Stream.of(1, 2, 3, 4)
        .reduce(100, (a, b) -> a + b)

returns the value of 110 since all the Integer elements in the Stream are added to the Integer 100. If the Stream is empty, 100 is returned.

    Stream.of(1, 2, 3, 4)
        .parallel()
        .reduce(
            0,
            (a, b) -> a + b,
            (a, b) -> a + b
        )

returns the value of 10 since this example simply adds all the Integer elements in the Stream beginning with 0. The Stream can be executed in parallel whereby the last lambda will be used to combine results from each thread. If the Stream is empty, 0 is returned.

iterator

    Iterator<String> iterator
        = Stream.of("B", "A", "C", "B")
            .iterator();

creates a new Iterator over all the elements in the Stream.

spliterator

    Spliterator<String> spliterator
        = Stream.of("B", "A", "C", "B")
            .spliterator();

creates a new Spliterator over all the elements in the Stream.

Primitive Stream Operations

Primitive streams (like IntStream and LongStream) provide similar functionality as ordinary streams but usually the parameter count and types differ so that primitive streams can accept more optimized function variants.

Here is a list of terminal operations that are available only for primitive streams:

Operation Parameter(s) Action

sum

-

Returns a reduction of the elements which is the sum of all elements in the stream

average

-

Returns a reduction of the elements which is the average of all elements in the stream (if any)

summaryStatistics

-

Returns a reduction of the elements which is a summary of a number of statistic measurements (min, max, sum, average and count)

sum

    IntStream.of(1, 2, 3, 4)
        .sum()

returns 10 because 10 is the sum of all elements in the Stream.

average

    IntStream.of(1, 2, 3, 4)
        .average()

returns OptionalDouble[2.5] because 2.5 is the average of all elements in the Stream. If the Stream is empty, OptionalDouble.empty() is returned.

summaryStatistics

    IntStream.of(1, 2, 3, 4)
        .summaryStatistics()

returns IntSummaryStatistics{count=4, sum=10, min=1, average=2.500000, max=4}.

If the stream is empty, IntSummaryStatistics{count=0, sum=0, min=2147483647, average=0.000000, max=-2147483648} is returned (max is initially set to Integer.MIN_VALUE which is -2147483648 and min is set to Integer.MAX_VALUE which is 2147483648).