diff --git a/src/main/java/org/springframework/data/util/Sink.java b/src/main/java/org/springframework/data/util/Sink.java new file mode 100644 index 000000000..55d3587e6 --- /dev/null +++ b/src/main/java/org/springframework/data/util/Sink.java @@ -0,0 +1,34 @@ +package org.springframework.data.util; + +import java.util.function.Consumer; + +import org.springframework.lang.Nullable; + +/** + * A simple {@link Consumer} that captures the instance handed into it. + * + * @author Oliver Drotbohm + * @since 2.4.12 + */ +class Sink implements Consumer { + + private T value; + + /** + * Returns the value captured. + * + * @return + */ + public T getValue() { + return value; + } + + /* + * (non-Javadoc) + * @see java.util.function.Consumer#accept(java.lang.Object) + */ + @Override + public void accept(@Nullable T t) { + this.value = t; + } +} diff --git a/src/main/java/org/springframework/data/util/StreamUtils.java b/src/main/java/org/springframework/data/util/StreamUtils.java index 0f8abfef8..f53a6736a 100644 --- a/src/main/java/org/springframework/data/util/StreamUtils.java +++ b/src/main/java/org/springframework/data/util/StreamUtils.java @@ -140,9 +140,26 @@ public interface StreamUtils { @Override @SuppressWarnings("null") public boolean tryAdvance(Consumer action) { - return lefts.tryAdvance(left -> rights.tryAdvance(right -> action.accept(combiner.apply(left, right)))); - } + Sink leftSink = new Sink(); + Sink rightSink = new Sink(); + + boolean leftAdvance = lefts.tryAdvance(leftSink); + + if (!leftAdvance) { + return false; + } + + boolean rightAdvance = rights.tryAdvance(rightSink); + + if (!rightAdvance) { + return false; + } + + action.accept(combiner.apply(leftSink.getValue(), rightSink.getValue())); + + return true; + } }, parallel); } } diff --git a/src/test/java/org/springframework/data/util/StreamUtilsTests.java b/src/test/java/org/springframework/data/util/StreamUtilsTests.java index 296473a74..1e961f306 100755 --- a/src/test/java/org/springframework/data/util/StreamUtilsTests.java +++ b/src/test/java/org/springframework/data/util/StreamUtilsTests.java @@ -42,4 +42,13 @@ public class StreamUtilsTests { assertThat(input).isEqualTo(output); } + + @Test // #2426 + void combinesInfiniteStreamCorrectly() { + + Stream indices = Stream.iterate(1L, n -> n + 1); + Stream lines = Stream.of("first line", "second line"); + + assertThat(StreamUtils.zip(indices, lines, (index, line) -> index + ":" + line).count()).isEqualTo(2); + } }