I read this api doc Stream api and it says ( three sentences in a paragraph )
"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."
"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."
I don't understand why intermediate and terminal operations are short-circuiting if, when presented with infinite input.
I don't understand third sentence as well why short-circuiting is necessary but insufficient condition for processing infinite stream to terminate normally in finite time.
It would be great if someone helps me to understand with a code example.
What I know about short-circuiting is like
for example, if( a && b ) { ... }
if a is false, you don't have to check b.
In Java logical operators, if the evaluation of a logical expression exits in between before complete evaluation, then it is known as Short-circuit. A short circuit happens because the result is clear even before the complete evaluation of the expression, and the result is returned.
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.
The terminal short-circuit operations in stream are findFirst(), findAny(), allMatch(), anyMatch(), and noneMatch().
A stream pipeline consists of a source (such as a Collection, an array, a generator function, or an I/O channel); followed by zero or more intermediate operations such as Stream. filter or Stream. map ; and a terminal operation such as Stream.
I don't understand why intermediate and terminal operations are short-circuiting if, when presented with infinite input.
Because it is stated that "An intermediate operation is short-circuiting if, when presented with infinite input, it may produce a finite stream as a result."
Example: limit()
if its input is an infinite stream the output is finite and then there is no necessity to try to consume all the input, so it is short-circuit because it produces an output in finite time even if the input can not be processed in finite time.
Stream<Integer> infiniteStream = Stream.iterate(0, i -> i + 1);
infiniteStream.limit(5).forEach(System.out::println);
produces an output and terminates in finite time even if the infiniteStream is infinite.
I don't understand third sentence as well why short-circuiting is necessary but insufficient condition for processing infinite stream to terminate normally in finite time.
Sentence is : "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."
Example : anyMatch
is a short-circuiting terminal operation but produces a result on an infinite stream only if a element of the input stream verifies the predicate.
Stream<Integer> infiniteStream = Stream.iterate(0, i -> i);
infiniteStream.anyMatch(x->x==1).forEach(System.out::println);
does not terminates but :
Stream<Integer> infiniteStream = Stream.iterate(0, i -> i);
infiniteStream.anyMatch(x->x==0).forEach(System.out::println);
does.
Short-circuiting in logical expressions is another kind of short-circuiting but you can consider what happens on expression like if (f() && g())
with f
and/or g
has infinite computations... Question: when does the expression can have a value? If f()
produces false
then even if g()
is an infinite computation the expression equals to false. Then in some way, &&
can short-cut some infinite computations.
In the context of Stream
and as the doc already suggests the short-circuiting operations are limit(n)
, findFirst()
etc.
Short-circuiting operations such as
limit(n)
orfindFirst()
can allow computations on infinite streams to complete in finite time.
e.g.
Stream stream;
stream.forEach(s -> {..do something}); // something is executed until all the elements of source are traversed
stream.limit(n).forEach(s -> {do something else}); // something else is executed just for 'n' times
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