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.
// 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.
// 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).
// 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).
// 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.
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).
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:
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
M | T | W | T | F | S | S |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |