Skip to content

StreamUtils.zip(infiniteStream, finiteStream, combiner).count() never returns #2426

Closed
@egilbert

Description

@egilbert

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();

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions