tsolakp
tsolakp

Reputation: 5948

Java stream operation invocations

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?

Upvotes: 14

Views: 669

Answers (2)

Makoto
Makoto

Reputation: 106508

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.

Upvotes: 3

Eugene
Eugene

Reputation: 121048

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.

Upvotes: 15

Related Questions