3

Can we somehow split stream into substreams with no more than N elements in Java? For example

Stream<Integer> s = Stream.of(1,2,3,4,5);
Stream<Stream<Integer>> separated = split(s, 2);
// after that separated should contain stream(1,2), stream(3,4), stream(5)

splitting by two streams solution is correct only for 2 streams, the same for N streams will be very ugly and write-only.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
maxpovver
  • 1,580
  • 14
  • 25
  • 2
    Possible duplicate of [Can you split a stream into two streams?](http://stackoverflow.com/questions/19940319/can-you-split-a-stream-into-two-streams) – PM 77-1 Dec 13 '16 at 17:47
  • 1
    No, you can't, not really. Collect into actual literal collections, not streams, and it'll be doable. – Louis Wasserman Dec 13 '16 at 18:58
  • 1
    This is a recurring [XY Problem](http://meta.stackexchange.com/a/66378). Instead of asking, how to split the Stream, think about what you actually want to do with the Stream(s). Ask, how to get the desired result from the Stream, not how to split the Stream. – Holger Dec 14 '16 at 10:16

2 Answers2

4

You can't split a Stream into 2 or more Streass easily and directly. The only way the procedural one consisting of collecting the elements to the List by the couples and mapping them back to Stream again:

Stream<Integer> s = Stream.of(1,2,3,4,5);
List<Integer> list = s.collect(Collectors.toList());
int size = list.size();
    
List<List<Integer>> temp = new ArrayList<>();
List<Integer> temp2 = new ArrayList<>();
    
int index = 0;
for (int i=0; i<size; i++) {
    temp2.add(list.get(i));
    if (i%2!=0) {
        temp.add(temp2);
        temp2 = new ArrayList<>();
    }
    if (i == size - 1) {
        temp.add(temp2);
    }
}
Stream<Stream<Integer>> stream = temp.stream().map(i -> i.stream());

As you see it's a really long way an not worth. Wouldn't be better to store the pairs in the List rather than Stream? The API is not used for data storage but their processing.

Neel Sandell
  • 429
  • 5
  • 12
Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
0

For example:

<T> Stream<Stream<T>> split(Stream<T> stream, int n) {
  final var it = stream.iterator();
  final Stream.Builder<Stream<T>> result = Stream.builder();
  while (it.hasNext()) {
    final Stream.Builder<T> buf = Stream.builder();
    for (int i = 0; i < n && it.hasNext(); i++) {
      buf.accept(it.next());
    }
    result.accept(buf.build());
  }
  return result.build();
}


Stream<Integer> s = Stream.of(1,2,3,4,5);
Stream<Stream<Integer>> separated = split(s, 2);
separated.map(x -> x.collect(Collectors.toList())).forEach(System.out::println);
[1, 2]
[3, 4]
[5]
Arsegg
  • 126
  • 1
  • 10