Skip to content
Oracle Certified Professional Java SE 17 Developer

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

Streams from a CharSequence – Streams

Streams from a CharSequence

The CharSequence.chars() method creates a finite sequential ordered IntStream from a sequence of char values. The IntStream must be transformed to a Stream<Character> in order to handle the values as Characters. The IntStream.mapToObj() method can be used for this purpose, as shown at (2). A cast is necessary at (2) in order to convert an int value to a char value which is autoboxed in a Character. Conversion between streams is discussed in §16.5, p. 934.

Click here to view code image

String strSource = “banananana”;
IntStream iStream = strSource.chars();                   // (1)
iStream.forEach(i -> System.out.print(i + ” “));         // Prints ints.
// 98 97 110 97 110 97 110 97 110 97
strSource.chars()
         .mapToObj(i -> (char)i)                         // (2) Stream<Character>
         .forEach(System.out::print);                    // Prints chars.
// banananana

The following default method for building IntStreams from a sequence of char values (e.g., String and StringBuilder) is defined in the java.lang.CharSequence interface (§8.4, p. 444):

default IntStream chars()

Creates a finite sequential ordered stream of int values by zero-extending the char values in this sequence.

Streams from a String

The following method of the String class can be used to extract text lines from a string:

Stream<String> lines()

Returns a stream of lines extracted from this string, separated by line terminators.

In the code below, the string at (1) contains three text lines separated by the line terminator (\n). A stream of element type String is created using this string as the source at (2). Each line containing the word “mistakes” in this stream is printed at (3).

Click here to view code image

String inputLines = “Wise men learn from their mistakes.\n”                 // (1)
                  + “But wiser men learn from the mistakes of others.\n”
                  + “And fools just carry on.”;
Stream<String> lStream = inputLines.lines();                                // (2)
lStream.filter(l -> l.contains(“mistakes”)).forEach(System.out::println);   // (3)

Output from the code:

Click here to view code image

Wise men learn from their mistakes.
But wiser men learn from the mistakes of others.

Archives

  • July 2024
  • June 2024
  • May 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • October 2023
  • September 2023
  • May 2023
  • March 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • July 2022
  • April 2022
  • March 2022
  • November 2021
  • October 2021
  • September 2021
  • July 2021
  • June 2021
  • March 2021
  • February 2021

Calendar

August 2022
M T W T F S S
1234567
891011121314
15161718192021
22232425262728
293031  
« Jul   Sep »

Categories

  • Aspects of Streams, Revisited
  • Converting between Stream Types
  • Execution Mode of a Stream
  • Mapping between Numeric Streams
  • Oracle Exams
  • Selecting Distinct Elements

Copyright Oracle Certified Professional Java SE 17 Developer 2025 | Theme by noranebula | Proudly powered by noranebula