Take while a predicate returns true

One of the most useful methods that was added to the Stream class, starting with JDK 9, was takeWhile​(Predicate<? super T> predicate). This method comes with two different behaviors, as follows:

  • If the stream is ordered, it returns a stream consisting of the longest prefix of elements taken from this stream that match the given predicate.
  • If the stream is unordered, and some (but not all) of the 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).

In the case of an ordered Stream, the longest prefix of elements is a contiguous sequence of elements of the stream that match with the given predicate.

Note that takeWhile() will discard the remaining stream once the given predicate returns false.

For example, fetching a list of 10 integers can be done as follows:

List<Integer> result = IntStream
.iterate(1, i -> i + 1)
.takeWhile(i -> i <= 10)
.boxed()
.collect(Collectors.toList());

This will give us the following output:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Alternatively, we could fetch a List of random even integers until the first generated value is less than 50:

List<Integer> result = new Random().ints(1, 100)
.filter(i -> i % 2 == 0)
.takeWhile(i -> i >= 50)
.boxed()
.collect(Collectors.toList());

We can even join the predicates in takeWhile():

List<Integer> result = new Random().ints(1, 100)
.takeWhile(i -> i % 2 == 0 && i >= 50)
.boxed()
.collect(Collectors.toList());

One possible output can be obtained as follows (it can be empty as well):

64, 76, 54, 68

How about fetching a List of random passwords until the first generated password doesn't contain the ! character?

Well, based on the helper we listed earlier, we can do this like so:

List<String> result = Stream.generate(Main::randomPassword)
.takeWhile(s -> s.contains("!"))
.collect(Collectors.toList());

One possible output can be obtained as follows (it can be empty as well):

0!dac!3c, 2!$!b2ac, 1d12ba1!

Now, let's assume that we have an unordered stream of integers. The following snippet of code takes a subset of elements that are less than or equal to 10:

Set<Integer> setOfInts = new HashSet<>(
Arrays.asList(1, 4, 3, 52, 9, 40, 5, 2, 31, 8));

List<Integer> result = setOfInts.stream()
.takeWhile(i -> i<= 10)
.collect(Collectors.toList());

One possible output is as follows (remember that, for an unordered stream, the result is nondeterministic):

1, 3, 4
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.206.69