Java streams 2. API overview

In Java 8, a stream was introduced as an object of an interface Stream, IntStream, LongStream, or DoubleStream of the package java.util.stream. All four stream interfaces have many similar methods:

        List.of(1, 2, 3)
                .stream()
                .filter(e -> e < 3)
                .forEach(System.out::print); //prints: 12

        List.of(1, 2, 3)
                .stream()
                .mapToInt(i -> i)    // creates IntStream
                .filter(e -> e < 3)
                .forEach(System.out::print); //prints: 12

The specialized numeric stream interfaces IntStream, LongStream, or DoubleStream have a few extra methods, like average() and sum(), specific to the numeric values. For example:

        int sum = List.of(1, 2, 3)
                .stream()
                .mapToInt(i -> i)   // creates IntStream
                .filter(e -> e < 3)
                .sum();
        System.out.println(sum);    //prints: 3

All the methods of stream interfaces are divided into three groups. As we have mentioned already in the previous article, two groups of methods are called operationsintermediate and terminal. Each operation is applied to each element of the stream, flowing through the processing pipeline.

Many operations accept a function as a parameter that represents the implementation of a single abstract method of an interface, called a functional interface; so, the operations themselves are just shells around the call to the method of the functional interface assigned as the type of the method parameter.

The third group of stream methods is static factories that produce Stream objects. We will talk about them in the following article of the series.

All the Java 8 Stream API is contained within java.util.stream package. In addition to the already described interfaces Stream, IntStream, LongStream, or DoubleStream, the package includes class Collectors that contains static factory methods that produce Collector objects. The interface Collector is accepted by the terminal operation collect(), which allows accumulating elements into collections, summarizing elements according to various criteria, etc.

Other members of java.util.stream package either support the described four stream interfaces or used for the implementation of these interfaces by stream processing library developers.

This is Java 8 Stream API

To conclude the overview of Java 8 Streams API, we need only to mention two points:

— the stream elements are typically processed sequentially, but can easily be converted to parallel processing by calling the method parallel() and back by calling the method sequential(). We will discuss the possible pitfalls and what to watch for during such a conversion later in one of the articles of the series;

— an operation can be stateless or stateful; for example, converting each String to int is a stateless, while the summing of all the numeric elements is a stateful operation; it is an important distinction because a stateful operation can be typically applied to the finite streams only, while stateless operations can work on infinite streams as well; also, one has to take certain measures while using stateful operations during parallel processing; we will discuss how to do it correctly later in one of the articles of the series.

To summarize:

— there are four interfaces that can represent a stream of data: Stream, IntStream, LongStream, and DoubleStream – all in the package java.util.stream since Java 8;

— each method of the stream interfaces belong to one of the three groups: factory methods, intermediate operations, terminal operations;

— a factory method returns an object of one of the stream interfaces;

— some operations receive a function (an implementation of a functional interface) as a parameter;

— an intermediate operation returns a stream interface object;

— a terminal operation returns the final result and/or produces a side effect;

— a stream can be finite (with a limited number of emitted elements) or infinite;

— a stream can be sequential or parallel (broken into sub-streams, each processed by a separate thread);

— an operation can be stateful or stateless;

— beware of using stateful operations while processing an infinite or a parallel stream.

See other posts on Java 8 streams and posts on other topics.
You can also use navigation pages for Java stream related blogs:
— Java 8 streams blog titles
— Create stream
— Stream operations
— Stream operation collect()
The source code of all the code examples is here in GitHub

, , ,

Send your comments using the link Contact or in response to my newsletter.
If you do not receive the newsletter, subscribe via link Subscribe under Contact.

Powered by WordPress. Designed by Woo Themes