Skip to content

Instantly share code, notes, and snippets.

@chklauser
Last active May 2, 2022 15:22
Show Gist options
  • Save chklauser/381a88c9aeb008510978014206532943 to your computer and use it in GitHub Desktop.
Save chklauser/381a88c9aeb008510978014206532943 to your computer and use it in GitHub Desktop.
A Java stream combinator that splits a stream into chunks of a fixed size. Last chunk in the stream might be smaller than the desired size. Ordering guarantees depend on underlying stream.
public final class ChunkedStreams {
private ChunkedStreams(){}
@SuppressWarnings("SameParameterValue")
public static <T> Stream<List<T>> chunks(Stream<T> sourceStream, int size) {
var source = sourceStream.spliterator();
return StreamSupport.stream(new Spliterator<>() {
final List<T> buf = new ArrayList<>();
@Override
public boolean tryAdvance(Consumer<? super List<T>> action) {
while (buf.size() < size) {
if (!source.tryAdvance(buf::add)) {
if (!buf.isEmpty()) {
action.accept(List.copyOf(buf));
buf.clear();
return true;
} else {
return false;
}
}
}
action.accept(List.copyOf(buf));
buf.clear();
return true;
}
@Override
public Spliterator<List<T>> trySplit() {
return null;
}
@Override
public long estimateSize() {
var sourceSize = source.estimateSize();
return sourceSize / size + (sourceSize % size != 0 ? 1 : 0);
}
@Override
public int characteristics() {
return NONNULL | ORDERED;
}
}, false);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment