Stream pipelines

By this topic, you have already learned different types of stream operations such as filter, map and reduce. Now is the time to start using these operations together and get into more details on the real stream pipelines. In a sense, the idea of this topic is to consolidate your knowledge about streams and to guide you through more complex practice exercises.

Streams of primitives

The generic Stream<T> class is used to process objects which are always represented by reference types. For example, to work with integers, it’s possible to create Stream<Integer> that wraps primitive int‘s into the Integer class. But this is not an efficient way to work with integers, since it needs additional wrapper objects. Fortunately, there are three primitive specialized types called IntStream, LongStream, and DoubleStream which can effectively process primitive values without extra boxing.

Grouping collectors

We have learned how to accumulate stream elements into a collection or a single value by using collect operation and Collectors class. However, besides that, the collect can offer other useful operations such as dividing stream elements into two or more groups or applying a collector to the result of another collector. In this topic, we will see how to sort the elements of a stream by using Collectors.partitioningBy and Collectors.groupingBy methods. We will also…


So far we know how to produce a single value from a stream of elements by using reduce operation. However, collecting stream elements into a collection such as a List or a Set is a much more popular scenario than reducing them to a single value. For that, Java Stream API provides a terminal operation called collect. In a combination with a utility stream.Collectors class that contains a lot of useful reduction operations, collect allows us…

Map and flatMap

ne of the most common tasks in programming is converting collections of objects to the new ones by applying the same function to each element in the collection. This task can be solved with a functional approach. Since you already know about Java Stream API, we are ready to take a closer look at the map and flatMap intermediate operations.

Taking elements

If you’d like to take only a certain number of elements from a stream or skip some of them, you can invoke the limit(n) or skip(m) methods. But what if you need to take or skip some elements until some condition is true? Starting from Java 9, streams have two convenient methods to do this. They can take or drop the longest contiguous subsequence of elements from the stream based on the given…

Reduction methods

While dealing with collections in Java, you can often face the challenge of reducing all collection elements to a single result. The example of such a problem is finding a bank account with the maximum amount of money among the collection of accounts or reducing account transaction values to the total amount of transferred money. Java Stream API provides several terminal operations that allow us to solve…

Stream filtering

Filtering is an important operation that allows us to obtain only those elements of the collection that meet a specified condition. For example, to get songs over seven minutes long among all your music library, we can filter songs by their duration. In this topic, we’ll figure out how to use Java Stream API intermediate filter operation to cope with such challenges.

Infinite streams

Collections in Java always have a finite number of elements because the memory of a computer is limited. However, Stream API allows us to operate on infinite streams of elements. It is possible due to the lazy nature of streams: creating an infinite stream is an intermediate operation, so it actually does not create elements until a terminal operation is executed. It is supposed that…