Java 9 Stream API Improvements

1. Overview

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

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 limitallMatch that actually serve for other purposes or write our own takeWhile implementation based on a Spliterator that, in turn, complicates such a simple issue.

With Java 9, the solution is easy:

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:

  • 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
  • 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)
  .forEach(System.out::println);

It can be associated with the corresponding for statement:

for (int i = 0; i < 10; ++i) {
    System.out.println(i);
}

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:

collection.stream()
  .flatMap(s -> {
      Integer temp = map.get(s);
      return temp != null ? Stream.of(temp) : Stream.empty();
  })
  .collect(Collectors.toList());

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:

collection.stream()
  .flatMap(s -> Stream.ofNullable(map.get(s)))
  .collect(Collectors.toList());

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.

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

Related posts:

Java Program to Solve Set Cover Problem assuming at max 2 Elements in a Subset
Java Program to Find the Connected Components of an UnDirected Graph
Giới thiệu SOAP UI và thực hiện test Web Service
Assertions in JUnit 4 and JUnit 5
Java Program to Implement Hash Tables Chaining with Doubly Linked Lists
Optional trong Java 8
Java Program to Implement Cubic convergence 1/pi Algorithm
Java Program to Check for balanced parenthesis by using Stacks
Java Program to Delete a Particular Node in a Tree Without Using Recursion
Merging Streams in Java
Show Hibernate/JPA SQL Statements from Spring Boot
Examine the internal DNS cache
The Thread.join() Method in Java
The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5
Java Program to Perform Preorder Non-Recursive Traversal of a Given Binary Tree
Guava – Join and Split Collections
Java Program to Convert a Decimal Number to Binary Number using Stacks
Java Program to Implement Bloom Filter
Biến trong java
Spring Data – CrudRepository save() Method
Spring Boot - CORS Support
Java Program to Evaluate an Expression using Stacks
Java Program to Implement Attribute API
Java Program to Implement Coppersmith Freivald’s Algorithm
REST Web service: Tạo ứng dụng Java RESTful Client với Jersey Client 2.x
Using Optional with Jackson
Java Program to Implement Hash Tables with Double Hashing
Display Auto-Configuration Report in Spring Boot
Spring Boot - Enabling HTTPS
ArrayList trong java
Java Program to Check Cycle in a Graph using Graph traversal
Generic Constructors in Java