Taking and Dropping Elements Using Predicates – Streams

Taking and Dropping Elements Using Predicates

Both the takeWhile() and the dropWhile() methods find the longest prefix of elements to take or drop from the input stream, respectively.

The code below at (1) and (2) illustrates the case for ordered streams. The take-While() method takes odd numbers from the input stream until a number is not odd, and short-circuits the processing of the stream—that is, it truncates the rest of the stream based on the predicate. The dropWhile() method, on the other hand, drops odd numbers from the input stream until a number is not odd, and passes the remaining elements to its output stream; that is, it skips elements in the beginning of the stream based on the predicate.

Click here to view code image

// Ordered stream:
Stream.of(1, 3, 5, 7, 8, 9, 11)                 // (1)
      .takeWhile(n -> n % 2 != 0)               // Takes longest prefix: 1 3 5 7
      .forEach(n -> System.out.print(n + ” “)); // 1 3 5 7
Stream.of(1, 3, 5, 7, 8, 9, 11)                 // (2)
      .dropWhile(n -> n % 2 != 0)               // Drops longest prefix:  1 3 5 7
      .forEach(n -> System.out.print(n + ” “)); // 8 9 11

Given an unordered stream, as shown below at (3), both methods return nondeterministic results: Any subset of matching elements can be taken or dropped, respectively.

Click here to view code image

// Unordered stream:
Set<Integer> iSeq = Set.of(1, 9, 4, 3, 7);      // (3)
iSeq.stream()
    .takeWhile(n -> n % 2 != 0)                 // Takes any subset of elements.
    .forEach(n -> System.out.print(n + ” “));   // Nondeterministic: 1 9 7
iSeq.stream()
    .dropWhile(n -> n % 2 != 0)                 // Drops any subset of elements.
    .forEach(n -> System.out.print(n + ” “));   // Nondeterministic: 4 3

Regardless of whether the stream is ordered or unordered, if all elements match the predicate, the takeWhile() method takes all the elements and the dropWhile() method drops all the elements, as shown below at (4) and (5).

Click here to view code image

// All match in ordered stream:                    (4)
Stream.of(1, 3, 5, 7, 9, 11)
      .takeWhile(n -> n % 2 != 0)               // Takes all elements.
      .forEach(n -> System.out.print(n + ” “)); // Ordered: 1 3 5 7 9 11
Stream.of(1, 3, 5, 7, 9, 11)
      .dropWhile(n -> n % 2 != 0)               // Drops all elements.
      .forEach(n -> System.out.print(n + ” “)); // Empty stream
// All match in unordered stream:                  (5)
Set<Integer> iSeq2 = Set.of(1, 9, 3, 7, 11, 5);
iSeq2.stream()
     .takeWhile(n -> n % 2 != 0)                // Takes all elements.
     .forEach(n -> System.out.print(n + ” “));  // Unordered: 9 11 1 3 5 7
iSeq2.stream()
     .dropWhile(n -> n % 2 != 0)                // Drops all elements.
     .forEach(n -> System.out.print(n + ” “));  // Empty stream

Regardless of whether the stream is ordered or unordered, if no elements match the predicate, the takeWhile() method takes no elements and the dropWhile() method drops no elements, as shown below at (6) and (7).

Click here to view code image

// No match in ordered stream:                     (6)
Stream.of(2, 4, 6, 8, 10, 12)
      .takeWhile(n -> n % 2 != 0)               // Takes no elements.
      .forEach(n -> System.out.print(n + ” “)); // Empty stream
Stream.of(2, 4, 6, 8, 10, 12)
      .dropWhile(n -> n % 2 != 0)               // Drops no elements.
      .forEach(n -> System.out.print(n + ” “)); // Ordered: 2 4 6 8 10 12
// No match in unordered stream:                   (7)
Set<Integer> iSeq3 = Set.of(2, 10, 8, 12, 4, 6);
iSeq3.stream()
     .takeWhile(n -> n % 2 != 0)                // Takes no elements.
     .forEach(n -> System.out.print(n + ” “));  // Empty stream

iSeq3.stream()
     .dropWhile(n -> n % 2 != 0)                // Drops no elements.
     .forEach(n -> System.out.print(n + ” “));  // Unordered: 8 10 12 2 4 6

Leave a Reply

Your email address will not be published. Required fields are marked *