-
Bug
-
Resolution: Fixed
-
P4
-
9
-
b105
-
Verified
Spliterator contract does not disable to split after advance. Though such possibility is never used in JDK, sometimes it's convenient to use it in third-party libraries. However spliterator produced by the stream which has upstream flatMap operation works incorrectly if trySplit() is called after tryAdvance(). Here's simple testcase:
Spliterator<String> spltr = Stream.of("a", "b", "c").flatMap(x -> Stream.of(x, x)) // duplicate each stream element
.parallel().spliterator();
spltr.tryAdvance(System.out::println); // prints "a"
Spliterator<String> prefix = spltr.trySplit(); // splits successfully
prefix.forEachRemaining(System.out::println); // prints "b", "b"
spltr.forEachRemaining(System.out::println); // prints "a", "c", "c"
Unexpectedly the second "a" is printed by the suffix part and prefix skips over it. There's even existing test method SpliteratorTestHelper::testMixedTraverseAndSplit, which fails when such spliterator is supplied to it.
Spliterator<String> spltr = Stream.of("a", "b", "c").flatMap(x -> Stream.of(x, x)) // duplicate each stream element
.parallel().spliterator();
spltr.tryAdvance(System.out::println); // prints "a"
Spliterator<String> prefix = spltr.trySplit(); // splits successfully
prefix.forEachRemaining(System.out::println); // prints "b", "b"
spltr.forEachRemaining(System.out::println); // prints "a", "c", "c"
Unexpectedly the second "a" is printed by the suffix part and prefix skips over it. There's even existing test method SpliteratorTestHelper::testMixedTraverseAndSplit, which fails when such spliterator is supplied to it.