package org.infinispan.functional.impl; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.BinaryOperator; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collector; import java.util.stream.Stream; import org.infinispan.commons.api.functional.Traversable; import org.infinispan.commons.util.CloseableIterator; import org.infinispan.commons.util.Closeables; public final class Traversables { public static <T> Traversable<T> of(Stream<T> stream) { return new StreamTraversable<>(stream); } public static <T> CloseableIterator<T> asIterator(Traversable<T> traversable) { if (traversable instanceof StreamTraversable) return Closeables.iterator(((StreamTraversable<T>) traversable).stream); else { List<T> collected = traversable.collect(ArrayList::new, ArrayList::add, ArrayList::addAll); return Closeables.iterator(collected.iterator()); } } private Traversables() { // Cannot be instantiated, it's just a holder class } // TODO: Attention! This is a very rudimentary/simplistic implementation! private static final class StreamTraversable<T> implements Traversable<T> { final Stream<T> stream; private StreamTraversable(Stream<T> stream) { this.stream = stream; } @Override public Traversable<T> filter(Predicate<? super T> p) { return new StreamTraversable<>(stream.filter(p)); } @Override public <R> Traversable<R> map(Function<? super T, ? extends R> f) { return new StreamTraversable<>(stream.map(f)); } @Override public <R> Traversable<R> flatMap(Function<? super T, ? extends Traversable<? extends R>> f) { Function<? super T, ? extends Stream<? extends R>> mapper = new Function<T, Stream<? extends R>>() { @Override public Stream<? extends R> apply(T t) { StreamTraversable<? extends R> applied = (StreamTraversable<? extends R>) f.apply(t); return applied.stream; } }; return new StreamTraversable<>(stream.flatMap(mapper)); } @Override public void forEach(Consumer<? super T> c) { stream.forEach(c); } @Override public T reduce(T z, BinaryOperator<T> folder) { return stream.reduce(z, folder); } @Override public Optional<T> reduce(BinaryOperator<T> folder) { return stream.reduce(folder); } @Override public <U> U reduce(U z, BiFunction<U, ? super T, U> mapper, BinaryOperator<U> folder) { return stream.reduce(z, mapper, folder); } @Override public <R> R collect(Supplier<R> s, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) { return stream.collect(s, accumulator, combiner); } @Override public <R, A> R collect(Collector<? super T, A, R> collector) { return stream.collect(collector); } @Override public long count() { return stream.count(); } @Override public boolean anyMatch(Predicate<? super T> p) { return stream.anyMatch(p); } @Override public boolean allMatch(Predicate<? super T> p) { return stream.allMatch(p); } @Override public boolean noneMatch(Predicate<? super T> predicate) { return stream.noneMatch(predicate); } @Override public Optional<T> findAny() { return stream.findAny(); } } }