Skip to main content

Java 8 - Streams - Introduction


Let's have a look at below code.

List<String> countries = Arrays.asList("Sri Lanka", "India", "Pakistan", "England", "Australia");

for (String country : countries) {
    if (country.length() > 7) {
        String upperCase = country.toUpperCase();

This code has several problems.
  • Process sequentially. Difficult to process parallel.
  • Complex codes.
  • Instruct how to do it, not what to do.
  • External loop. (developer has to create the loop).

To overcome these kind of problems and get the maximum from multi-core processors Java 8 introduces Stream API.

The same code can be re-written using stream as below.
        .filter(country -> country.length() > 7)
        .map(country -> country.toUpperCase())

As you can see it works like builder pattern. We chain several operations using a dot.
We can think of this as a sql query. Instead of how to it, we are instructing what to do.
We didn't provide a loop here, instead it uses internal iteration.

Stream operations have 3 stages.
  • Create stream using an array, collection.
  • Transform stream using intermediate operations.
  • Reduce the result using terminal operations.

Intermediate Operations

Intermediate operations return another stream which helps to connect multiple operations.. These operations doesn't process as in the order we provide. Instead it merge possible operations into a single operation. Another important point is these operations process lazily. Operation doesn't invoke until a terminal operation is called.
Ex:- map, flatMap, filter, distinct, limit

Terminal Operations

These operations end the stream and produce a result. Result is not a stream. It can be void, a List, Integer, etc.
Ex: forEach, collect, reduce, count, max, min