Terminal and Intermediate operations in the Java 8 Stream API

Terminal and Intermediate operations in the Java 8 Stream API

When working with the Stream API in Java 8, there are two groups of methods that you need to be aware of.

These two groups are referred to as terminal and intermediate operators.

Intermediate operators

These are the methods in the Stream API that returns a new Stream, these are:

  • distinct – Will only let through unique values, based on the objects equals method.
  • filter – Takes a Predicate that should return true or false. True if the object should be let through.
  • flatMap – Will replace each object in the the current stream with a new stream.
  • map – Returns a stream, where each the given function has been applied to each object in the stream.
  • peek – Lets you peek into the stream before a certain operation. The peek operation will only take place when the stream is actual processed.
  • sorted – Will return a Stream sorted by it natural order, determined by the compareTo method of Objects processed by the Stream.
  • limit – Sets a limit for the number of objects that the Stream will process.

Terminal operators

These are the operations in the Stream API are methods that consumes the Stream and can produce an result, these are:

  • allMatch – Will process the given predicate on all objects in the stream, and if all has been evaluated to true, it will return true. The processing of the stream will be stopped if the predicate returns false.
  • anyMatch – Almost the same as allMatch, with the difference that it will stop processing if the Predicate returns true.
  • collect – Converts the stream into a collection, such as a List.
  • count – Counts the number of elements in the stream.
  • findAny – Finds any element in the stream, must not be the first one. And running this method several times on the same stream might return different results.
  • findFirst – Finds the first element in the stream.
  • forEach – Takes an Consumer and perform the action on each element in the stream.
  • max – Will find the max for the stream, based on the specified comparator.
  • min – Will find the min for the stream, based on the specified comparator.
  • noneMatch – Takes a Predicate and executes it on all elements in the stream, the first element that will return true, the processing of the stream will stop.
  • reduce – Will reduce the elements in the Stream into a single BinaryOperator.
  • toArray – Converts the Stream into an Array.

So why is it useful to know the difference between intermediate and terminal operations, well have a look at the following:


1
2
List<String> cities = asList("Washington","Paris","London","Copenhagen","Stockholm");
cities.stream().map(String::toUpperCase).findFirst();

This will not convert every element to upper case, it will only do this on the first element and the terminate (because of findFirst).
This can also be useful to know that you can pass around the stream, and nothing will be executed, until you call a terminal method on it.

For example calling different methods for building up the Stream (adding different intermediates based on business logic and so on).

Leave a Reply

Your email address will not be published. Required fields are marked *