Java stream operation invocations
up vote
12
down vote
favorite
Can anyone point to a official Java documentation which describes how many times Stream will invoke each "non-interfering and stateless" intermediate operation for each element.
For example:
Arrays.asList("1", "2", "3", "4").stream()
.filter(s -> check(s))
.forEach(s -> System.out.println(s));
public boolean check(Object o)
return true;
The above currently will invoke check
method 4 times.
Is it possible that in the current or future versions of JDKs the check
method gets executed more or less times than the number of elements in the stream created from List or any other standard Java API?
java java-8 java-stream
|
show 1 more comment
up vote
12
down vote
favorite
Can anyone point to a official Java documentation which describes how many times Stream will invoke each "non-interfering and stateless" intermediate operation for each element.
For example:
Arrays.asList("1", "2", "3", "4").stream()
.filter(s -> check(s))
.forEach(s -> System.out.println(s));
public boolean check(Object o)
return true;
The above currently will invoke check
method 4 times.
Is it possible that in the current or future versions of JDKs the check
method gets executed more or less times than the number of elements in the stream created from List or any other standard Java API?
java java-8 java-stream
4
Is there some motive behind this question? Like, you want to add unit test like verify(times(4)).check(anyBool) such that it doesn't fail in future?
– Aayush Kumar Singha
23 hours ago
1
I do not see a reason why thatstream
would ever return more than4
values?
– Mark
23 hours ago
The motive is that if check also does important processing for each element then I want to be sure that it does only once for each element in the stream.
– tsolakp
23 hours ago
4
Thefilter
predicate is supposed to be stateless.
– Radiodef
23 hours ago
1
@chrylis. I don't think it will make any difference.
– tsolakp
22 hours ago
|
show 1 more comment
up vote
12
down vote
favorite
up vote
12
down vote
favorite
Can anyone point to a official Java documentation which describes how many times Stream will invoke each "non-interfering and stateless" intermediate operation for each element.
For example:
Arrays.asList("1", "2", "3", "4").stream()
.filter(s -> check(s))
.forEach(s -> System.out.println(s));
public boolean check(Object o)
return true;
The above currently will invoke check
method 4 times.
Is it possible that in the current or future versions of JDKs the check
method gets executed more or less times than the number of elements in the stream created from List or any other standard Java API?
java java-8 java-stream
Can anyone point to a official Java documentation which describes how many times Stream will invoke each "non-interfering and stateless" intermediate operation for each element.
For example:
Arrays.asList("1", "2", "3", "4").stream()
.filter(s -> check(s))
.forEach(s -> System.out.println(s));
public boolean check(Object o)
return true;
The above currently will invoke check
method 4 times.
Is it possible that in the current or future versions of JDKs the check
method gets executed more or less times than the number of elements in the stream created from List or any other standard Java API?
java java-8 java-stream
java java-8 java-stream
edited 7 hours ago
Mani Grover
111214
111214
asked 23 hours ago
tsolakp
4,40411219
4,40411219
4
Is there some motive behind this question? Like, you want to add unit test like verify(times(4)).check(anyBool) such that it doesn't fail in future?
– Aayush Kumar Singha
23 hours ago
1
I do not see a reason why thatstream
would ever return more than4
values?
– Mark
23 hours ago
The motive is that if check also does important processing for each element then I want to be sure that it does only once for each element in the stream.
– tsolakp
23 hours ago
4
Thefilter
predicate is supposed to be stateless.
– Radiodef
23 hours ago
1
@chrylis. I don't think it will make any difference.
– tsolakp
22 hours ago
|
show 1 more comment
4
Is there some motive behind this question? Like, you want to add unit test like verify(times(4)).check(anyBool) such that it doesn't fail in future?
– Aayush Kumar Singha
23 hours ago
1
I do not see a reason why thatstream
would ever return more than4
values?
– Mark
23 hours ago
The motive is that if check also does important processing for each element then I want to be sure that it does only once for each element in the stream.
– tsolakp
23 hours ago
4
Thefilter
predicate is supposed to be stateless.
– Radiodef
23 hours ago
1
@chrylis. I don't think it will make any difference.
– tsolakp
22 hours ago
4
4
Is there some motive behind this question? Like, you want to add unit test like verify(times(4)).check(anyBool) such that it doesn't fail in future?
– Aayush Kumar Singha
23 hours ago
Is there some motive behind this question? Like, you want to add unit test like verify(times(4)).check(anyBool) such that it doesn't fail in future?
– Aayush Kumar Singha
23 hours ago
1
1
I do not see a reason why that
stream
would ever return more than 4
values?– Mark
23 hours ago
I do not see a reason why that
stream
would ever return more than 4
values?– Mark
23 hours ago
The motive is that if check also does important processing for each element then I want to be sure that it does only once for each element in the stream.
– tsolakp
23 hours ago
The motive is that if check also does important processing for each element then I want to be sure that it does only once for each element in the stream.
– tsolakp
23 hours ago
4
4
The
filter
predicate is supposed to be stateless.– Radiodef
23 hours ago
The
filter
predicate is supposed to be stateless.– Radiodef
23 hours ago
1
1
@chrylis. I don't think it will make any difference.
– tsolakp
22 hours ago
@chrylis. I don't think it will make any difference.
– tsolakp
22 hours ago
|
show 1 more comment
2 Answers
2
active
oldest
votes
up vote
15
down vote
This does not have to do with the source of the stream, but rather the terminal operation and optimization done in the stream implementation itself. For example:
Stream.of(1,2,3,4)
.map(x -> x + 1)
.count();
Since java-9, map
will not get executed a single time.
Or:
someTreeSet.stream()
.sorted()
.findFirst();
sorted
might not get executed at all, since the source is a TreeSet
and getting the first element is trivial, but if this is implemented inside stream API or not, is a different question.
So the real answer here - it depends, but I can't imagine one operation that would get executed more that the numbers of elements in the source.
2
"but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify aComparator
for sorting, itscompare
will definitely be invoked more times than the number of elements, but that's just nitpicking. +1
– Fureeish
23 hours ago
1
@Fureeish no no, very good nitpick, indeed you are right; but it seemssorted
is the only one that could do that.distinct
does not for example
– Eugene
23 hours ago
1
Some time ago I asked this question about jdk8flatMap
(also see this related question). In short, in jdk8&9flatMap
is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.
– Federico Peralta Schaffner
22 hours ago
1
@FedericoPeraltaSchaffner as said earlier I can write it asStream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println);
does it mean that it gets visited more than once?
– Eugene
22 hours ago
2
4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
– Federico Peralta Schaffner
22 hours ago
|
show 9 more comments
up vote
3
down vote
From the documentation:
Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.
By that virtue, because filter
is an intermediate operation which creates a new Stream
as part of its operation, due to its laziness, it will only ever invoke the filter predicate once per element as part of its rebuilding of the stream.
The only way that your method would possibly have a different number of invocations against it in the stream is if the stream were somehow mutated between states, which given the fact that nothing in a stream actually runs until the terminal operation, would only realistically be possible due to a bug upstream.
So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
– tsolakp
22 hours ago
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
15
down vote
This does not have to do with the source of the stream, but rather the terminal operation and optimization done in the stream implementation itself. For example:
Stream.of(1,2,3,4)
.map(x -> x + 1)
.count();
Since java-9, map
will not get executed a single time.
Or:
someTreeSet.stream()
.sorted()
.findFirst();
sorted
might not get executed at all, since the source is a TreeSet
and getting the first element is trivial, but if this is implemented inside stream API or not, is a different question.
So the real answer here - it depends, but I can't imagine one operation that would get executed more that the numbers of elements in the source.
2
"but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify aComparator
for sorting, itscompare
will definitely be invoked more times than the number of elements, but that's just nitpicking. +1
– Fureeish
23 hours ago
1
@Fureeish no no, very good nitpick, indeed you are right; but it seemssorted
is the only one that could do that.distinct
does not for example
– Eugene
23 hours ago
1
Some time ago I asked this question about jdk8flatMap
(also see this related question). In short, in jdk8&9flatMap
is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.
– Federico Peralta Schaffner
22 hours ago
1
@FedericoPeraltaSchaffner as said earlier I can write it asStream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println);
does it mean that it gets visited more than once?
– Eugene
22 hours ago
2
4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
– Federico Peralta Schaffner
22 hours ago
|
show 9 more comments
up vote
15
down vote
This does not have to do with the source of the stream, but rather the terminal operation and optimization done in the stream implementation itself. For example:
Stream.of(1,2,3,4)
.map(x -> x + 1)
.count();
Since java-9, map
will not get executed a single time.
Or:
someTreeSet.stream()
.sorted()
.findFirst();
sorted
might not get executed at all, since the source is a TreeSet
and getting the first element is trivial, but if this is implemented inside stream API or not, is a different question.
So the real answer here - it depends, but I can't imagine one operation that would get executed more that the numbers of elements in the source.
2
"but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify aComparator
for sorting, itscompare
will definitely be invoked more times than the number of elements, but that's just nitpicking. +1
– Fureeish
23 hours ago
1
@Fureeish no no, very good nitpick, indeed you are right; but it seemssorted
is the only one that could do that.distinct
does not for example
– Eugene
23 hours ago
1
Some time ago I asked this question about jdk8flatMap
(also see this related question). In short, in jdk8&9flatMap
is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.
– Federico Peralta Schaffner
22 hours ago
1
@FedericoPeraltaSchaffner as said earlier I can write it asStream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println);
does it mean that it gets visited more than once?
– Eugene
22 hours ago
2
4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
– Federico Peralta Schaffner
22 hours ago
|
show 9 more comments
up vote
15
down vote
up vote
15
down vote
This does not have to do with the source of the stream, but rather the terminal operation and optimization done in the stream implementation itself. For example:
Stream.of(1,2,3,4)
.map(x -> x + 1)
.count();
Since java-9, map
will not get executed a single time.
Or:
someTreeSet.stream()
.sorted()
.findFirst();
sorted
might not get executed at all, since the source is a TreeSet
and getting the first element is trivial, but if this is implemented inside stream API or not, is a different question.
So the real answer here - it depends, but I can't imagine one operation that would get executed more that the numbers of elements in the source.
This does not have to do with the source of the stream, but rather the terminal operation and optimization done in the stream implementation itself. For example:
Stream.of(1,2,3,4)
.map(x -> x + 1)
.count();
Since java-9, map
will not get executed a single time.
Or:
someTreeSet.stream()
.sorted()
.findFirst();
sorted
might not get executed at all, since the source is a TreeSet
and getting the first element is trivial, but if this is implemented inside stream API or not, is a different question.
So the real answer here - it depends, but I can't imagine one operation that would get executed more that the numbers of elements in the source.
answered 23 hours ago
Eugene
66k992158
66k992158
2
"but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify aComparator
for sorting, itscompare
will definitely be invoked more times than the number of elements, but that's just nitpicking. +1
– Fureeish
23 hours ago
1
@Fureeish no no, very good nitpick, indeed you are right; but it seemssorted
is the only one that could do that.distinct
does not for example
– Eugene
23 hours ago
1
Some time ago I asked this question about jdk8flatMap
(also see this related question). In short, in jdk8&9flatMap
is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.
– Federico Peralta Schaffner
22 hours ago
1
@FedericoPeraltaSchaffner as said earlier I can write it asStream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println);
does it mean that it gets visited more than once?
– Eugene
22 hours ago
2
4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
– Federico Peralta Schaffner
22 hours ago
|
show 9 more comments
2
"but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify aComparator
for sorting, itscompare
will definitely be invoked more times than the number of elements, but that's just nitpicking. +1
– Fureeish
23 hours ago
1
@Fureeish no no, very good nitpick, indeed you are right; but it seemssorted
is the only one that could do that.distinct
does not for example
– Eugene
23 hours ago
1
Some time ago I asked this question about jdk8flatMap
(also see this related question). In short, in jdk8&9flatMap
is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.
– Federico Peralta Schaffner
22 hours ago
1
@FedericoPeraltaSchaffner as said earlier I can write it asStream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println);
does it mean that it gets visited more than once?
– Eugene
22 hours ago
2
4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
– Federico Peralta Schaffner
22 hours ago
2
2
"but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify a
Comparator
for sorting, its compare
will definitely be invoked more times than the number of elements, but that's just nitpicking. +1– Fureeish
23 hours ago
"but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify a
Comparator
for sorting, its compare
will definitely be invoked more times than the number of elements, but that's just nitpicking. +1– Fureeish
23 hours ago
1
1
@Fureeish no no, very good nitpick, indeed you are right; but it seems
sorted
is the only one that could do that. distinct
does not for example– Eugene
23 hours ago
@Fureeish no no, very good nitpick, indeed you are right; but it seems
sorted
is the only one that could do that. distinct
does not for example– Eugene
23 hours ago
1
1
Some time ago I asked this question about jdk8
flatMap
(also see this related question). In short, in jdk8&9 flatMap
is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.– Federico Peralta Schaffner
22 hours ago
Some time ago I asked this question about jdk8
flatMap
(also see this related question). In short, in jdk8&9 flatMap
is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.– Federico Peralta Schaffner
22 hours ago
1
1
@FedericoPeraltaSchaffner as said earlier I can write it as
Stream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println);
does it mean that it gets visited more than once?– Eugene
22 hours ago
@FedericoPeraltaSchaffner as said earlier I can write it as
Stream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println);
does it mean that it gets visited more than once?– Eugene
22 hours ago
2
2
4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
– Federico Peralta Schaffner
22 hours ago
4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
– Federico Peralta Schaffner
22 hours ago
|
show 9 more comments
up vote
3
down vote
From the documentation:
Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.
By that virtue, because filter
is an intermediate operation which creates a new Stream
as part of its operation, due to its laziness, it will only ever invoke the filter predicate once per element as part of its rebuilding of the stream.
The only way that your method would possibly have a different number of invocations against it in the stream is if the stream were somehow mutated between states, which given the fact that nothing in a stream actually runs until the terminal operation, would only realistically be possible due to a bug upstream.
So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
– tsolakp
22 hours ago
add a comment |
up vote
3
down vote
From the documentation:
Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.
By that virtue, because filter
is an intermediate operation which creates a new Stream
as part of its operation, due to its laziness, it will only ever invoke the filter predicate once per element as part of its rebuilding of the stream.
The only way that your method would possibly have a different number of invocations against it in the stream is if the stream were somehow mutated between states, which given the fact that nothing in a stream actually runs until the terminal operation, would only realistically be possible due to a bug upstream.
So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
– tsolakp
22 hours ago
add a comment |
up vote
3
down vote
up vote
3
down vote
From the documentation:
Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.
By that virtue, because filter
is an intermediate operation which creates a new Stream
as part of its operation, due to its laziness, it will only ever invoke the filter predicate once per element as part of its rebuilding of the stream.
The only way that your method would possibly have a different number of invocations against it in the stream is if the stream were somehow mutated between states, which given the fact that nothing in a stream actually runs until the terminal operation, would only realistically be possible due to a bug upstream.
From the documentation:
Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.
By that virtue, because filter
is an intermediate operation which creates a new Stream
as part of its operation, due to its laziness, it will only ever invoke the filter predicate once per element as part of its rebuilding of the stream.
The only way that your method would possibly have a different number of invocations against it in the stream is if the stream were somehow mutated between states, which given the fact that nothing in a stream actually runs until the terminal operation, would only realistically be possible due to a bug upstream.
answered 23 hours ago
Makoto
78.9k15122164
78.9k15122164
So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
– tsolakp
22 hours ago
add a comment |
So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
– tsolakp
22 hours ago
So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
– tsolakp
22 hours ago
So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
– tsolakp
22 hours ago
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53234586%2fjava-stream-operation-invocations%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
4
Is there some motive behind this question? Like, you want to add unit test like verify(times(4)).check(anyBool) such that it doesn't fail in future?
– Aayush Kumar Singha
23 hours ago
1
I do not see a reason why that
stream
would ever return more than4
values?– Mark
23 hours ago
The motive is that if check also does important processing for each element then I want to be sure that it does only once for each element in the stream.
– tsolakp
23 hours ago
4
The
filter
predicate is supposed to be stateless.– Radiodef
23 hours ago
1
@chrylis. I don't think it will make any difference.
– tsolakp
22 hours ago