Wednesday, September 27, 2017

Java 9 Streams : takeWhile() method

In Java 9, comes with a few good additions to the Stream API. For more information on the Java 8 Streams, go to the Java 8 Page. The following new methods were added to the Java 9 Stream API.
  1. takeWhile
  2. dropWhile
  3. iterate
  4. ofNullable
In this post we will take a look at the takeWhile() method.

takeWhile() method

In Stream API, takeWhile() Method takes a Predicate(function returning true or false) as an argument, and returns the set of elements of the stream that match the Predicate. However, this behavior varies between ordered and unordered streams.
Stream takeWhile(Predicate predicate)
In all the examples below, We will use the following list as a starting point, unless mentioned otherwise.
List<String> list = List.of("returns", "if", "this", "stream", "is", "ordered,", "stream", "consisting", "of", "the",
  "longest", "prefix", "of", "elements", "taken", "from", "this", "stream", "that", "match", "the", "given",
  "predicate");
As you can see, the sorted version of the list will look like this
consisting, elements, from, given, if, is, longest, match, of, of, ordered,, predicate, prefix, returns, stream, stream, stream, taken, that, the, the, this, this

For Ordered Stream

From the Javadoc
If this stream is ordered then the longest prefix is a contiguous sequence of elements of this 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.
This effectively means that if for an ordered list, takeWhile() will return a value only if the first element in this stream matches the predicate. If the first element doesn't match the predicate, we get back empty stream. You can see this behavior in the following example where we Predicate is to check if the length of a string is less than 4. Since the first element of the sorted stream "consists" is longer than 4 characters, we get back an empty stream.
  list
   .stream()
   .sorted()
   .takeWhile(x -> x.length() < 4)
   .forEach(System.out::println);
However, if the first element of the stream matches the predicate, then we will get the first few elements of the Stream that match the predicate. As soon as the predicate returns false, takeWhile() stops, even if there are any subsequent elements that match the predicate further downstream. In the following example, we check for strings length greater than 2, which will return "consisting, elements, from, given", and stops before "if".
list
 .stream()
 .sorted()
 .takeWhile(x -> x.length() > 2)
 .forEach(System.out::println);
 
Output:
consisting
elements
from
given 
Another example
list
   .stream()
   .sorted()
   .takeWhile(x -> x.contains("c"))
   .forEach(System.out::println);
   
Output:
consisting

For Unordered Stream

From the Javadoc
If this stream is unordered, and some (but not all) elements of this stream match the given predicate, then the behavior of this operation is nondeterministic; it is free to take any subset of matching elements (which includes the empty set).
list
  .stream()
  .takeWhile(x -> x.contains("t"))
  .forEach(System.out::println);
  Output:
  returns
The following Stream of number where we check for number less than 7,
Stream.of(1,5,3,2,4,9,7)
   .takeWhile(x->x <7)
   .forEach(System.out::println);
   
Output:
1
5
3
2
4
Finally, Here is the full code
package com.aoj.java9.collections;

import java.util.List;
import java.util.stream.Stream;

public class Java9StreamsTakeWhile {
 public static void main(String[] args) {
  List<String> list = List.of("returns", "if", "this", "stream", "is", "ordered,", "stream", "consisting", "of", "the",
    "longest", "prefix", "of", "elements", "taken", "from", "this", "stream", "that", "match", "the", "given",
    "predicate");

  list.stream().sorted().forEach(System.out::println);
  
  list
   .stream()
   .sorted()
   .takeWhile(x -> x.length() > 2)
   .forEach(System.out::println);

  list
   .stream()
   .sorted()
   .takeWhile(x -> x.contains("c"))
   .forEach(System.out::println);

  list
   .stream()
   .sorted()
   .takeWhile(x -> x.length() < 4)
   .forEach(System.out::println);

  list
  .stream()
  .takeWhile(x -> x.contains("t"))
  .forEach(System.out::println);
  
  Stream.of(1,5,3,2,4,9,7)
   .takeWhile(x->x <7)
   .forEach(System.out::println);
 }

}

No comments:

Post a Comment

Popular Posts