diff --git a/jdk/src/share/classes/java/util/stream/SliceOps.java b/jdk/src/share/classes/java/util/stream/SliceOps.java index 78fd3d7f0d5..ac538f2d86c 100644 --- a/jdk/src/share/classes/java/util/stream/SliceOps.java +++ b/jdk/src/share/classes/java/util/stream/SliceOps.java @@ -598,9 +598,9 @@ final class SliceOps { final Node.Builder nb = op.makeNodeBuilder(sizeIfKnown, generator); Sink opSink = op.opWrapSink(helper.getStreamAndOpFlags(), nb); helper.copyIntoWithCancel(helper.wrapSink(opSink), spliterator); - // It is necessary to truncate here since the result at the root - // can only be set once - return doTruncate(nb.build()); + // There is no need to truncate since the op performs the + // skipping and limiting of elements + return nb.build(); } else { Node node = helper.wrapAndCopyInto(helper.makeNodeBuilder(-1, generator), diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java index 29086fa351d..afa1b012653 100644 --- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java @@ -26,13 +26,16 @@ import org.testng.annotations.Test; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; import java.util.function.Function; +import java.util.stream.Collectors; import java.util.stream.DoubleStream; import java.util.stream.IntStream; import java.util.stream.LambdaTestHelpers; import java.util.stream.LongStream; import java.util.stream.OpTestCase; import java.util.stream.Stream; +import java.util.stream.StreamSupport; import java.util.stream.StreamTestDataProvider; import java.util.stream.TestData; @@ -192,6 +195,53 @@ public class SliceOpTest extends OpTestCase { } } + public void testSkipLimitOpsWithNonSplittingSpliterator() { + class NonSplittingNotSubsizedOrderedSpliterator implements Spliterator { + Spliterator s; + + NonSplittingNotSubsizedOrderedSpliterator(Spliterator s) { + assert s.hasCharacteristics(Spliterator.ORDERED); + this.s = s; + } + + @Override + public boolean tryAdvance(Consumer action) { + return s.tryAdvance(action); + } + + @Override + public void forEachRemaining(Consumer action) { + s.forEachRemaining(action); + } + + @Override + public Spliterator trySplit() { + return null; + } + + @Override + public long estimateSize() { + return s.estimateSize(); + } + + @Override + public int characteristics() { + return s.characteristics() & ~(Spliterator.SUBSIZED); + } + + @Override + public Comparator getComparator() { + return s.getComparator(); + } + } + List list = IntStream.range(0, 100).boxed().collect(Collectors.toList()); + TestData.OfRef data = TestData.Factory.ofSupplier( + "Non splitting, not SUBSIZED, ORDERED, stream", + () -> StreamSupport.stream(new NonSplittingNotSubsizedOrderedSpliterator<>(list.spliterator()))); + + testSkipLimitOps("testSkipLimitOpsWithNonSplittingSpliterator", data); + } + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) public void testLimitOps(String name, TestData.OfRef data) { List limits = sizes(data.size());