In scala those methods works fine but in java9 dropWhile works differently I think.
Here is example for takeWhile
Stream.of("a", "b", "c", "de", "f", "g", "h")
.peek(System.out::println)
.takeWhile(s -> s.length() <= 1)
.collect(Collectors.toList());
Output is fine: a, b, c, de, [a, b, c] It does not process elements after "de" so it works as expected
But dropWhile works in different way that I expect:
Stream.of("a", "b", "c", "de", "f", "g", "h")
.peek(s -> System.out.print(s + ", "))
.dropWhile(s -> s.length() <= 1)
.collect(Collectors.toList());
Output is: a, b, c, de, f, g, h, [de, f, g, h]
So it's not stopping after "de" element, it's processing whole collection.
Why is it processing whole collection? I know, that it's needed to take all elements and collect it to the List but shouldn't it stop processing after "de" element?
It seems, there is a fundamental misunderstanding about how peek
works. It is not associated with the next subsequently chained operation, like dropWhile
, but the entire Stream pipeline behind it. And it does not make a distinction between “processing elements” and “take all elements”.
So the simple code
Stream.of("a", "b", "c", "de", "f", "g", "h")
.peek(System.out::println)
.collect(Collectors.toList());
“takes all elements”, but prints them as they are passed from the Stream source to the Collector.
In your example, it makes no difference, whether an element is passed to the predicate of dropWhile
or directly to the Collector
, in either case, it will be reported by the peek
operation placed before both.
If you use
Stream.of("a", "b", "c", "de", "f", "g", "h")
.dropWhile(s -> {
System.out.println("dropWhile: "+s);
return s.length() <= 1;
})
.peek(s -> System.out.println("collecting "+s))
.collect(Collectors.toList());
instead, it will print
dropWhile: a
dropWhile: b
dropWhile: c
dropWhile: de
collecting de
collecting f
collecting g
collecting h
showing how the evaluation of dropWhile
’s predicate stops after the first unaccepted element whereas the transfer to the Collector
starts with that element.
This differs from the takeWhile
where both, the predicate evaluation and the collector, stop consuming elements, so there is no consumer left and the entire Stream pipeline can stop iterating the source.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With