I was practicing stream. Then got this strange behavior. I can't figure out the reason. That's why asking for help.
I wrote this:
IntStream.iterate(10, i -> i - 2)
.limit(5)
.sorted()
.takeWhile(i -> i > 2)
.forEach(System.out::println);
This is giving me nothing in the console, which is expected. When I am seeing the stream chain in IntelliJ IDEA, getting this:
So, after the execution of sorted() it is returning only one element (that element is 2 in the image) to the pipeline.
Now I commented the takeWhile() call. Like this:
IntStream.iterate(10, i -> i - 2)
.limit(5)
.sorted()
// .takeWhile(i -> i > 2)
.forEach(System.out::println);
This is also printing in the console as expected(from 10 to 2 with a difference of 2).
But problem is, this time sorted() returned 5 elements to pipeline. When I am seeing the stream chain in IntelliJ IDEA, getting this:
My question is, why the difference is seen in calling sorted()? If there is a takeWhile() after sorted() then it is returning one element. If I am commenting takeWhile(), sorted() is returning stream of 5 elements.
Is JVM doing anything here for achieving better performance?
Thanks in advance.....
Stream.sorted()
is a stateful operation, so it is actually maintaining the [2, 4, 6, 8, 10]
state. However, it will only send 1 item at a time.
So, Initially it will send 1 entry: '2'
to takeWhile
operator which can then reject the entry and stop the stream chain. That is why you are seeing sorted returning only 2
to takeWhile
operator.
But, when sorted is not present, takeWhile
will get 10
as the entry. And as the condition is true, stream will continue until takeWhile
receives 2
.
Edit:
When takeWhile
is not present, you are getting all 5 items as output because you have 5 items in stream chain and there is no takeWhile
to stop the stream chain.
In Intellij's Stream Trace, On the right side of sorted you are seeing how many elements are being passed to next operator after performing sorted()
operation.
In the first case, only 1 element is being passed to takeWhile()
as takeWhile()
is terminating the stream chain after receiving '2'
. But in the second case all the elements are being passed to forEach
.
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