Is there any way in Java 8 to group the elements in a java.util.stream.Stream
without collecting them? I want the result to be a Stream
again. Beca
There's no way to do it using standard Stream API. In general you cannot do it as it's always possible that new item will appear in future which belongs to any of already created groups, so you cannot pass your group to downstream analysis until you process all the input.
However if you know in advance that items to be grouped are always adjacent in input stream, you can solve your problem using third-party libraries enhancing Stream API. One of such libraries is StreamEx which is free and written by me. It contains a number of "partial reduction" operators which collapse adjacent items into single based on some predicate. Usually you should supply a BiPredicate
which tests two adjacent items and returns true if they should be grouped together. Some of partial reduction operations are listed below:
collapse(Objects::equals)
is useful to remove adjacent duplicates from the stream.StreamEx<T>
is converted to StreamEx<List<T>>
). For example, stringStream.groupRuns((a, b) -> a.charAt(0) == b.charAt(0))
will create stream of Lists of strings where each list contains adjacent strings started with the same letter.Other partial reduction operations include intervalMap, runLengths() and so on.
All partial reduction operations are lazy, parallel-friendly and quite efficient.
Note that you can easily construct a StreamEx
object from regular Java 8 stream using StreamEx.of(stream)
. Also there are methods to construct it from array, Collection, Reader, etc. The StreamEx
class implements Stream
interface and 100% compatible with standard Stream API.