Sometimes I want to perform a set of operations on a stream, and then process the resulting stream two different ways with other operations.
Can I do this without ha
I used this great answer to write following class:
public class SplitStream implements Stream {
private final Supplier> streamSupplier;
public SplitStream(Supplier> t) {
this.streamSupplier = t;
}
@Override
public Stream filter(Predicate super T> predicate) {
return streamSupplier.get().filter(predicate);
}
@Override
public Stream map(Function super T, ? extends R> mapper) {
return streamSupplier.get().map(mapper);
}
@Override
public IntStream mapToInt(ToIntFunction super T> mapper) {
return streamSupplier.get().mapToInt(mapper);
}
@Override
public LongStream mapToLong(ToLongFunction super T> mapper) {
return streamSupplier.get().mapToLong(mapper);
}
@Override
public DoubleStream mapToDouble(ToDoubleFunction super T> mapper) {
return streamSupplier.get().mapToDouble(mapper);
}
@Override
public Stream flatMap(Function super T, ? extends Stream extends R>> mapper) {
return streamSupplier.get().flatMap(mapper);
}
@Override
public IntStream flatMapToInt(Function super T, ? extends IntStream> mapper) {
return streamSupplier.get().flatMapToInt(mapper);
}
@Override
public LongStream flatMapToLong(Function super T, ? extends LongStream> mapper) {
return streamSupplier.get().flatMapToLong(mapper);
}
@Override
public DoubleStream flatMapToDouble(Function super T, ? extends DoubleStream> mapper) {
return streamSupplier.get().flatMapToDouble(mapper);
}
@Override
public Stream distinct() {
return streamSupplier.get().distinct();
}
@Override
public Stream sorted() {
return streamSupplier.get().sorted();
}
@Override
public Stream sorted(Comparator super T> comparator) {
return streamSupplier.get().sorted(comparator);
}
@Override
public Stream peek(Consumer super T> action) {
return streamSupplier.get().peek(action);
}
@Override
public Stream limit(long maxSize) {
return streamSupplier.get().limit(maxSize);
}
@Override
public Stream skip(long n) {
return streamSupplier.get().skip(n);
}
@Override
public void forEach(Consumer super T> action) {
streamSupplier.get().forEach(action);
}
@Override
public void forEachOrdered(Consumer super T> action) {
streamSupplier.get().forEachOrdered(action);
}
@Override
public Object[] toArray() {
return streamSupplier.get().toArray();
}
@Override
public A[] toArray(IntFunction generator) {
return streamSupplier.get().toArray(generator);
}
@Override
public T reduce(T identity, BinaryOperator accumulator) {
return streamSupplier.get().reduce(identity, accumulator);
}
@Override
public Optional reduce(BinaryOperator accumulator) {
return streamSupplier.get().reduce(accumulator);
}
@Override
public U reduce(U identity, BiFunction accumulator, BinaryOperator combiner) {
return streamSupplier.get().reduce(identity, accumulator, combiner);
}
@Override
public R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) {
return streamSupplier.get().collect(supplier, accumulator, combiner);
}
@Override
public R collect(Collector super T, A, R> collector) {
return streamSupplier.get().collect(collector);
}
@Override
public Optional min(Comparator super T> comparator) {
return streamSupplier.get().min(comparator);
}
@Override
public Optional max(Comparator super T> comparator) {
return streamSupplier.get().max(comparator);
}
@Override
public long count() {
return streamSupplier.get().count();
}
@Override
public boolean anyMatch(Predicate super T> predicate) {
return streamSupplier.get().anyMatch(predicate);
}
@Override
public boolean allMatch(Predicate super T> predicate) {
return streamSupplier.get().allMatch(predicate);
}
@Override
public boolean noneMatch(Predicate super T> predicate) {
return streamSupplier.get().noneMatch(predicate);
}
@Override
public Optional findFirst() {
return streamSupplier.get().findFirst();
}
@Override
public Optional findAny() {
return streamSupplier.get().findAny();
}
@Override
public Iterator iterator() {
return streamSupplier.get().iterator();
}
@Override
public Spliterator spliterator() {
return streamSupplier.get().spliterator();
}
@Override
public boolean isParallel() {
return streamSupplier.get().isParallel();
}
@Override
public Stream sequential() {
return streamSupplier.get().sequential();
}
@Override
public Stream parallel() {
return streamSupplier.get().parallel();
}
@Override
public Stream unordered() {
return streamSupplier.get().unordered();
}
@Override
public Stream onClose(Runnable closeHandler) {
return streamSupplier.get().onClose(closeHandler);
}
@Override
public void close() {
streamSupplier.get().close();
}
}
When you call any method of it's class, it delegates call to
streamSupplier.get()
So, instead of:
Supplier supplier = () ->
IntStream.range(1, 100).filter(n -> n % 2 == 0);
supplier.get().filter(...);
supplier.get().filter(...);
You can do:
SplitStream stream =
new SplitStream<>(() -> IntStream.range(1, 100).filter(n -> n % 2 == 0).boxed());
stream.filter(...);
stream.filter(...);
You can expand it to work with IntStream, DoubleStream, etc...