In Java, the Stream.takeWhile and Stream.dropWhile methods are introduced in Java 9. These operations allow you to process a stream conditionally based on a predicate, controlling how many elements to take or discard from the stream.
Here’s how they work:
Stream.takeWhile(predicate)
- Operation: This method takes elements from the stream as long as the given predicate evaluates to
true. It stops processing as soon as the predicate evaluates tofalse, even if there are more elements in the stream. - Key Point: It works on a lazily-evaluated stream and stops as soon as the predicate fails.
Example:
package org.kodejava.util.stream;
import java.util.List;
import java.util.stream.Collectors;
public class TakeWhileExample {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7);
// Take numbers while they are less than 5
List<Integer> result = numbers.stream()
.takeWhile(n -> n < 5) // Stop as soon as an element >= 5
.collect(Collectors.toList());
System.out.println(result); // Output: [1, 2, 3, 4]
}
}
Stream.dropWhile(predicate)
- Operation: This method discards elements from the stream as long as the given predicate evaluates to
true. Once the predicate evaluates tofalse, it will take the rest of the elements (even if they later match the predicate again). - Key Point: Opposite to
takeWhile, it skips the matching elements first, and continues from where the condition becomesfalse.
Example:
package org.kodejava.util.stream;
import java.util.List;
import java.util.stream.Collectors;
public class DropWhileExample {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7);
// Drop numbers while they are less than 5
List<Integer> result = numbers.stream()
.dropWhile(n -> n < 5) // Skip elements < 5; start when n >= 5
.collect(Collectors.toList());
System.out.println(result); // Output: [5, 6, 7]
}
}
Differences Between takeWhile and dropWhile
| Aspect | takeWhile | dropWhile |
|---|---|---|
| Purpose | Takes elements until the predicate fails. | Skips elements until the predicate fails. |
| Processing Stops | At the first failure of the predicate. | After the first failure of the predicate. |
| Returned Elements | Elements satisfying the predicate, up to the first failure. | Elements from the first failure onward. |
Notes:
- Order-sensitive: These methods respect the order of the stream. If you use unordered streams, results might vary.
- Early stopping:
takeWhileworks efficiently because it short-circuits the moment the predicate fails. - Infinite streams: Both can work with infinite streams but are best applied with a condition that eventually stops the operation.
Example with Infinite Stream:
package org.kodejava.util.stream;
import java.util.stream.Stream;
import java.util.List;
import java.util.stream.Collectors;
public class InfiniteStreamExample {
public static void main(String[] args) {
List<Integer> taken = Stream.iterate(1, n -> n + 1)
.takeWhile(n -> n <= 5) // Stops when n > 5
.collect(Collectors.toList());
System.out.println(taken); // Output: [1, 2, 3, 4, 5]
}
}
With these tools, you can write concise and declarative stream-processing logic.
