I am reading about Java streams' short-circuiting operations and found in some articles that skip()
is a short-circuiting operation.
In another article they didn't mention skip()
as a short-circuiting operation.
Now I am confused; is skip()
a short-circuiting operation or not?
In the javadoc for allMatch(Predicate), anyMatch(Predicate), noneMatch(Predicate), findAny(), and findFirst(): This is a short-circuiting terminal operation. However, note that findFirst and findAny doesn't have a Predicate . So they can both return immediately upon seeing the first/any value.
A terminal operation is short-circuiting if, when presented with infinite input, it may terminate in finite time. Having a short-circuiting operation in the pipeline is a necessary, but not sufficient, condition for the processing of an infinite stream to terminate normally in finite time.
Difference between limit() and skip() :The limit() method returns a reduced stream of first N elements but skip() method returns a stream of remaining elements after skipping first N elements.
limit. Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length. This is a short-circuiting stateful intermediate operation.
From the java doc under the "Stream operations and pipelines" section :
An intermediate operation is short-circuiting if, when presented with infinite input, it may produce a finite stream as a result. A terminal operation is short-circuiting if, when presented with infinite input, it may terminate in finite time.
Emphasis mine.
if you were to call skip
on an infinite input it won't produce a finite stream hence not a short-circuiting operation.
The only short-circuiting intermediate operation in JDK8 is limit
as it allows computations on infinite streams to complete in finite time.
Example:
if you were to execute this program with the use of skip
:
String[] skip = Stream.generate(() -> "test") // returns an infinite stream
.skip(20)
.toArray(String[]::new);
it will not produce a finite stream hence you would eventually end up with something along the lines of "java.lang.OutOfMemoryError: Java heap space".
whereas if you were to execute this program with the use of limit
, it will cause the computation to finish in a finite
time:
String[] limit = Stream.generate(() -> "test") // returns an infinite stream
.limit(20)
.toArray(String[]::new);
Just want to add my two cents here, this idea in general of a short-circuiting a stream is infinitely complicated (at least to me and at least in the sense that I have to scratch my head twice usually). I will get to skip
at the end of the answer btw.
Let's take this for example:
Stream.generate(() -> Integer.MAX_VALUE);
This is an infinite stream, we can all agree on this. Let's short-circuit it via an operation that is documented to be as such (unlike skip
):
Stream.generate(() -> Integer.MAX_VALUE).anyMatch(x -> true);
This works nicely, how about adding a filter
:
Stream.generate(() -> Integer.MAX_VALUE)
.filter(x -> x < 100) // well sort of useless...
.anyMatch(x -> true);
What will happen here? Well, this never finishes, even if there is a short-circuiting operation like anyMatch
- but it's never reached to actually short-circuit anything.
On the other hand, filter
is not a short-circuiting operation, but you can make it as such (just as an example):
someList.stream()
.filter(x -> {
if(x > 3) throw AssertionError("Just because");
})
Yes, it's ugly, but it's short-circuiting... That's how we (emphases on we, since lots of people, disagree) implement short-circuiting reduce
- throw an Exception that has no stack traces.
In java-9
there was an addition of another intermediate operation that is short-circuiting: takeWhile
that acts sort of like limit
but for a certain condition.
And to be fair, the bulk of the answer about skip
was an already give by Aomine, but the most simple answer is that it is not documented as such. And in general (there are cases when documentation is corrected), but that is the number one indication you should look at. See limit
and takeWhile
for example that clearly says:
This is a short-circuiting stateful intermediate operation
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