Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Stream - what is the difference between filter() and dropWhile()

With Java 9 method dropWhile() was added to the Stream API. When I read the documentation, I found out that it is very similar to Java 8 filter() method.

Am I missing something? What is the difference between these methods?

like image 352
Dev_panda Avatar asked Jul 20 '26 20:07

Dev_panda


2 Answers

Let's have a look at this example:

Stream.of(1, 2, 3, 1)
       .dropWhile(i -> i < 2)
       .forEach(System.out::println);

System.out.println("====");

Stream.of(1, 2, 3, 1)
       .filter(i -> i < 2)
       .forEach(System.out::println);

which will give the following output:

2
3
1
====
1
1

Firstly, in ordered streams dropWhile drops only the longest prefix of matching elements (see the docs). Also, you can see that filter specifies which elements need to pass, while dropWhile which to remove.

like image 74
vladtkachuk Avatar answered Jul 22 '26 12:07

vladtkachuk


filter - is a stateless intermediate operation which always returns a stream consisting only of elements the matches the given predicate.

Returns a stream consisting of the elements of this stream that match the given predicate.

dropWhile - is a stateful intermediate operation, which also expects a predicate and basically acts like a stateful filter. After the first element which doesn't match the predicate has been encountered, dropWhile() stops discarding elements from the stream.

If this stream is ordered then the longest prefix is a contiguous sequence of elements of this stream that match the given predicate.

If this stream is unordered, and some (but not all) elements of this stream match the given predicate, then the behavior of this operation is nondeterministic; it is free to drop any subset of matching elements (which includes the empty set).

To understand the difference between in behavior of the dropWhile with ordered and unordered stream, let's consider the following examples.

That would an example of unordered stream:

Set<Integer> numbers = Set.of(9, 1, 2, 3, 4, 5, 6, 7, 8);

numbers.stream()
    .dropWhile(i -> i < 9)
    .forEach(System.out::print);

Output can be for example 912, it would range from 9 to 123456789 (meaning that all elements might be present, the order in the output would be unpredictable). Because the stream is unordered elements from the source might appear in the stream, and dropWhile() can be switched off at any point of execution, that's what the phrase "behavior is nondeterministic" in this case means.

Now let's take a look at the ordered stream:

List<Integer> numbers = List.of(9, 1, 2, 3, 4, 5, 6, 7, 8);
    
numbers.stream()
    .dropWhile(i -> i < 9)
    .forEach(System.out::print);

Output:

912345678

Since 9, the very first element in the stream, doesn't match the predicate, it will never be evaluated again, dropWhile() is being switched off and all element would reach the terminal operation.

like image 28
Alexander Ivanchenko Avatar answered Jul 22 '26 12:07

Alexander Ivanchenko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!