Description
Short description
StreamsUtils.zip(infiniteStream, finiteStream, combiner).count()
never returns the size of the stream even though it is finite.
Detailed description
In spring-data-commons v2.3.9.RELEASE.
var zippedStream = StreamUtils.zip(leftStream, rightStream, combiner);
When consuming zippedStream
, even if the end of rightStream
is reached, leftStream
is still being consumed.
Each attempt at consuming from zippedStream
consume one item from leftStream
, and then try (and fails) to consume from rightStream
.
When consuming zippedStream
entirely, leftStream
is consumed entirely as well. If leftStream
is much larger than rightStream
, this might lead to performance issues. When leftStream
is infinite, it's impossible to consume zippedStream
entirely, despite it being finite If rightStream
is finite.
Steps to reproduce
This concats indexes to a stream of strings.
import org.springframework.data.util.StreamUtils;
var indices = Stream.iterate(1L, n -> n + 1).peek(n -> System.out.println(n));
var lines = Stream.of("first line", "second line");
var indexedLines = StreamUtils.zip(indices, lines, (index, line) -> index + ":" + line);
indexedLines.count();
Expected behaviour
Prints 1, 2 and possibly 3 to the standard output, and evaluates to 2.
Actual behaviour
Keeps printing numbers to the standard output until the process is killed.
Workaround
Putting the "short" stream first avoids the issue.
import org.springframework.data.util.StreamUtils;
var indices = Stream.iterate(1L, n -> n + 1).peek(n -> System.out.println(n));
var lines = Stream.of("first line", "second line");
var indexedLines = StreamUtils.zip(lines, indices, (line, index) -> index + ":" + line);
indexedLines.count();