Separator state after "consumed" in the stream

I think I'm having a problem with the assumption I made: if the spliterator element is not consumed by the stream, the splitter will still be able to advance it. It doesn't seem like that.

Here is some code to demonstrate:

import java.util.Spliterator; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; /** * Created by dsmith on 7/21/15. */ public class SpliteratorTest { public static void main(String[] args) { System.out.println("Test 1"); test1(); System.out.println("Test 2"); test2(); } public static void test1() { final Spliterator<String> spliterator1 = Stream.of("a", "b", "c", "d", "e", "f").spliterator(); StreamSupport.stream(spliterator1, false). limit(3). collect(Collectors.toList()); System.out.println("spliterator1.estimateSize() = " + spliterator1.estimateSize()); } public static void test2() { final Spliterator<String> spliterator1 = Stream.of("a", "b", "c", "d", "e", "f").spliterator(); final Spliterator<String> spliterator2 = Stream.of("1", "2", "3", "4", "5", "6").spliterator(); Stream.of(StreamSupport.stream(spliterator1, false), StreamSupport.stream(spliterator2, false)). flatMap(Function.identity()). limit(3). collect(Collectors.toList()); System.out.println("spliterator1.estimateSize() = " + spliterator1.estimateSize()); System.out.println("spliterator2.estimateSize() = " + spliterator2.estimateSize()); } } 

It is output:

 Test 1 spliterator1.estimateSize() = 3 Test 2 spliterator1.estimateSize() = 0 spliterator2.estimateSize() = 6 

I understand that delimiters can be shared ... but it seems not to be shared, sequential access intuitively saves unused elements.

In test2, it seems spliterator1 is completely consumed after the stream. But in test1 it is not completely consumed.

Is there anything I can do to achieve the desired behavior, or am I just doing what I shouldn't do?

+6
source share
1 answer

This is an implementation detail, but the flatMap method currently works in that it does not break into contents or flatMap over it one element at a time. He absorbs it all in one go. If you execute Stream.concat(...) instead of flatMap , you should see the difference:

 Stream.concat(StreamSupport.stream(spliterator1, false), StreamSupport.stream(spliterator2, false)). limit(3). collect(Collectors.toList()); System.out.println("spliterator1.estimateSize() = " + spliterator1.estimateSize()); System.out.println("spliterator2.estimateSize() = " + spliterator2.estimateSize()); 

output:

 spliterator1.estimateSize() = 3 spliterator2.estimateSize() = 6 

Am I just doing what I should not do?

In short, yes. There are no promises in the Streams library in what state it will leave the delimiter after a partial crawl.

+5
source

All Articles