Java 9 Stream API Improvements – Java 9流API的改进

最后修改: 2016年 11月 10日


1. Overview


In this quick write-up, we are going to focus on the new interesting Stream API improvements coming in Java 9.

在这篇快速的文章中,我们将重点介绍Java 9中新的有趣的Stream API改进。

2. Stream Takewhile/Dropwhile


Discussions about these methods have appeared repeatedly on StackOverflow (the most popular is this one).


Imagine that we want to generate a Stream of Strings by adding one character to the previous Stream‘s value until the length of the current value in this Stream is lower than 10.


How would we solve it in Java 8? We could use one of the short-circuiting intermediate operations like limit, allMatch that actually serve for other purposes or write our own takeWhile implementation based on a Spliterator that, in turn, complicates such a simple issue.

在Java 8中我们如何解决这个问题呢?我们可以使用其中一个短路的中间操作,如limitallMatch,这些中间操作实际上是为其他目的服务的。Predicate)”>allMatch,它们实际上是为其他目的服务的,或者在takeWhile的基础上编写我们自己的Spliterator,而这又会使这样一个简单的问题复杂化。

With Java 9, the solution is easy:

有了Java 9,解决这个问题就很容易了。

Stream<String> stream = Stream.iterate("", s -> s + "s")
  .takeWhile(s -> s.length() < 10);

The takeWhile operation takes a Predicate which is applied to elements to determine the longest prefix of these elements (if a stream is ordered) or a subset of the stream’s elements (when a stream is unordered).


To move forward, we had better understand what terms “the longest prefix” and “a Stream’s subset” mean:

为了向前推进,我们必须更好地理解 “最长的前缀 “和 “一个Stream的子集 “等术语的含义。

  • the longest prefix is a contiguous sequence of elements of the stream that match the given predicate. The first element of the sequence is the first element of this stream, and the element immediately following the last element of the sequence does not match the given predicate
  • a Stream’s subset is a set of some (but not all) elements of the Stream match the given predicate.

After introducing these key terms, we can easily comprehend another new dropWhile operation.


It does exactly the opposite of takeWhile. If a stream is ordered, the dropWile returns a stream consisting of the remaining elements of this Stream after dropping the longest prefix of elements that match the given predicate.


Otherwise, if a Stream is unordered, the dropWile returns a stream consisting of the remaining elements of this Stream after dropping a subset of elements that match the given predicate.


Let’s throw away the first five elements by using the preceding obtained Stream:


stream.dropWhile(s -> !s.contains("sssss"));

Simply put, the dropWhile operation will remove elements while the given predicate for an element returns true and stops removing on the first predicate’s false.


3. Stream Iterate


The next new feature is the overloaded iterate method for finite Streams generation. Not to be confused with the finite variant which returns an infinite sequential ordered Stream produced by some function.


A new iterate slightly modifies this method by adding a predicate which applies to elements to determine when the Stream must terminate. Its usage is very convenient and concise:


Stream.iterate(0, i -> i < 10, i -> i + 1)

It can be associated with the corresponding for statement:


for (int i = 0; i < 10; ++i) {

4. Stream Ofnullable

4.Stream Ofnullable

There are some situations when we need to put an element into a Stream. Sometimes, this element may be a null, but we don’t want that our Stream contains such values. It causes of writing either an if statement or a ternary operator which checks whether an element is a null.


Assuming that collection and map variables, have been created and filled successfully, have a look at the following example:

  .flatMap(s -> {
      Integer temp = map.get(s);
      return temp != null ? Stream.of(temp) : Stream.empty();

To avoid such boilerplate code, the ofNullable method has been added to the Stream class. With this method the preceding sample can be simply transformed into:

  .flatMap(s -> Stream.ofNullable(map.get(s)))

5. Conclusion


We considered major changes of Stream API in Java 9 and how these improvements will help us to write more emphatic programs with fewer efforts.

我们考虑了Java 9中Stream API的主要变化,以及这些改进将如何帮助我们以更少的努力编写更强调的程序。

As always, the code snippets can be found over on Github.