Stream API received a few nice additions with the Java 9. Both Stream interfaces as well as Collectors were updated. Let's start with the new collectors. To show these improvements we will use next classes:

Flatmapping and filtering collectors

Two new collectors were added to Collectors. Both of them are intended to be used for multilevel reduction, mostly for downstream collecting with Collectors#groupingBy() and Collectors#partitioningBy(). Two collectors that we want to look at are:

  • Collectors#filtering() - receives a filtering predicate and a downstream collector. Applies a filter and collects the filtered items with a provided collector.
  • Collectors#flatMapping() - receives a mapper and a downstream collector. Applies a flat mapping operation, using the mapper and then collects the mapped items with a provided collector.

Their names are pretty descriptive about what they do. Here are a few examples using these new collectors as well as the code without them but which will produce the same results:
These collectors can be applied to simple collect operations as well:

New methods in Stream

All stream interfaces (Stream/IntStream/LongStream/DoubleStream) received next new methods:
  • takeWhile - allows to provide a predicate which will determine when to stop processing stream elements.
  • dropWhile - allows to provide a predicate which will determine till when stream elements will be skipped and not processed.
  • iterate - it's an additional overload of previously present methods, which receives one more parameter. this new parameter is a predicate which determines when to terminate a stream. It allows to create finite streams opposed to previous methods which could crate only infinite streams. The intention of this method is to provide a functional-stream alternative of a for loop with the index.
Besides that Stream interface also received Stream#ofNullable() method which receives on element and if it is a null then an empty stream will be returned (Stream#empty()) or a stream of that one element otherwise. This method might be very useful in cases where some Stream concatenation occurs and some elements might be null, but nulls shouldn't be present. 
Here are a few examples using these new methods:

Conclusions 

All of these additional collectors and stream methods might become quite handy, just one thing that I'd like to add - don't rush and change all your for loops with the iterate+foreach methods use them if it feels appropriate or is needed.

To be continued...