Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until end-of-day today:

>> GET ACCESS NOW

November Discount Launch 2022 – TEMP TOP (NPI)
We’re finally running a Black Friday launch. All Courses are 30% off until end-of-day today:

>> GET ACCESS NOW

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 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.

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
  • 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)
  .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.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until end-of-day today:

>> GET ACCESS NOW

Generic footer banner
Comments are closed on this article!