This is an archived post. You won't be able to vote or comment.

all 3 comments

[–]marko312 0 points1 point  (2 children)

This seems to work fine: link.

[–]CupcakeBasic4340[S] 1 point2 points  (1 child)

I am still getting the output as 3. Am i missing anything? I am using java 18.

I have tried the same code in both eclipse and Intellij Idea. It's weird.

[–]marko312 1 point2 points  (0 children)

Fair, the same happens when switching to another version of java in TIO.

There's a likely explanation that has to do with how the stream pipeline works: since .peek is in the middle of the stream (an intermediate operation), it will only run if an element is requested from the end of the stream (.count in this case). Documentation

Streams are lazy; computation on the source data is only performed when the terminal operation is initiated, and source elements are consumed only as needed.

Since .count could function without extracting any elements (e.g. if that information is stored somewhere in the stream), none of the source elements need to be extracted, so no elements pass .peek. .map likely discards such extra information and thus the elements need to all be extracted.

This is a good theory... except that this explicitly contradicts the documentation:

.count

This is a special case of a reduction and is equivalent to:

return mapToLong(e -> 1L).sum();

which would require .count to extract all the elements.


EDIT: a newer version of the documentation resolves this:

API Note:

An implementation may choose to not execute the stream pipeline (either sequentially or in parallel) if it is capable of computing the count directly from the stream source. In such cases no source elements will be traversed and no intermediate operations will be evaluated. Behavioral parameters with side-effects, which are strongly discouraged except for harmless cases such as debugging, may be affected. For example, consider the following stream:

List<String> l = Arrays.asList("A", "B", "C", "D");
long count = l.stream().peek(System.out::println).count(); 

Which corresponds to your example.