Last active
May 2, 2022 15:22
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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