I want to split a single Stream into a Stream of Streams based on the contents of the Streams. The resulting the St
You can use my StreamEx library. It has groupRuns which does the job:
List input = Arrays.asList(1, 1, 1, 2, 2, 2, 3, 6, 7, 7, 1, 1);
Stream> streams = StreamEx.of(input).filter(this::isOdd)
.groupRuns(Integer::equals)
.map(List::stream);
Usage example:
streams.map(s -> StreamEx.of(s).joining(",")).forEach(System.out::println);
Output:
1,1,1
3
7,7
1,1
Similar to protonpack library there's a custom spliterator inside, but using StreamEx you can take advantage of parallel processing (the protonpack does not split at all).
In sequential processing at most one intermediate list resides in memory at a time (others are eligible for GC). If you still worry about memory consumption (for example, you have very long groups), there is an alternative way to solve this task since the StreamEx 0.3.3:
Stream> streams = StreamEx.of(input).filter(this::isOdd)
.runLengths()
.mapKeyValue(StreamEx::constant);
The runLengths method returns the stream of entries where key is the element and value is the number of adjacent repeating elements. After that StreamEx.constant is used which is shortcut for Stream.generate(() -> value).limit(length). So you will have a constant intermediate memory consumption even for very long groups. Of course this version is also parallel-friendly.
Update: StreamEx 0.3.3 is released, thus the second solution is now eligible as well.