Skip to content

Instantly share code, notes, and snippets.

@VAlux
Created October 28, 2021 17:23
Show Gist options
  • Save VAlux/0c21170367e2ccf4d701c12d0bfdc51e to your computer and use it in GitHub Desktop.
Save VAlux/0c21170367e2ccf4d701c12d0bfdc51e to your computer and use it in GitHub Desktop.
Java Spliterator implementation for a sliding window stream handling
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Objects;
import java.util.Queue;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public final class SlidingWindowSpliterator<T> implements Spliterator<Stream<T>> {
private final Queue<T> windowBuffer;
private final Iterator<T> sourceIterator;
private final int windowSize;
private final int size;
public SlidingWindowSpliterator(Collection<T> source, int windowSize) {
this.windowBuffer = new ArrayDeque<>(windowSize);
this.sourceIterator = Objects.requireNonNull(source).iterator();
this.windowSize = windowSize;
this.size = calculateSize(source, windowSize);
}
@Override
@SuppressWarnings("unchecked")
public boolean tryAdvance(Consumer<? super Stream<T>> action) {
if (windowSize < 1) {
return false;
}
while (sourceIterator.hasNext()) {
windowBuffer.add(sourceIterator.next());
if (windowBuffer.size() == windowSize) {
// arrays in java...
action.accept(Arrays.stream((T[]) windowBuffer.toArray(new Object[0])));
windowBuffer.poll();
return sourceIterator.hasNext();
}
}
return false;
}
@Override
public Spliterator<Stream<T>> trySplit() {
return null;
}
@Override
public long estimateSize() {
return size;
}
@Override
public int characteristics() {
return ORDERED | SIZED | NONNULL;
}
private int calculateSize(final Collection<T> source, final int windowSize) {
if (source.size() < windowSize) {
return 0;
}
return source.size() - windowSize + 1;
}
public static <T> Stream<Stream<T>> stream(final Collection<T> source, final int windowSize) {
return StreamSupport.stream(new SlidingWindowSpliterator<>(source, windowSize), false);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment