FluentIterator implements ImmutableIterator<T> { public List<FluentIterator<T>> tee(int n) { Function<Iterator<T>, FluentIterator<T>> f = FluentIterator::fluent; return Iterators.takeAll(Iterators.map(Iterators.tee(this, n).iterator(), f)); } FluentIterator(Iterator<T> t); static FluentIterator<T> fluent(Iterator<T> t); @Override boolean hasNext(); @Override T next(); boolean weakEquals(Iterator<T> s, int n); @SuppressWarnings("unchecked") FluentIterator<T> filter(Predicate<? super T> p); boolean any(Predicate<? super T> p); boolean all(Predicate<? super T> p); @SuppressWarnings("unchecked") FluentIterator<T> concat(Iterator... ts); FluentIterator<T> peek(Consumer<? super T> cs); List<T> take(int n); List<T> takeAll(); FluentIterator<T> limit(int n); List<FluentIterator<T>> tee(int n); FluentIterator<Pair<T, S>> zip(Iterator<S> s, boolean weak); FluentIterator<List<T>> groupBy(Function<T, K> key); FluentIterator<List<T>> groupBy(); FluentIterator<T> skipDuplicates(Function<T, K> key); FluentIterator<T> skipDuplicates(); FluentIterator<T> keepFirst(Function<? super T, ? extends K> key); FluentIterator<T> keepLast(Function<? super T, ? extends K> key); FluentIterator<V> map(Function<T, V> f); FluentIterator<T> map(Iterator<T> t, BinaryOperator<T> f); T reduce(BinaryOperator<T> f); V reduce(BiFunction<V, T, V> f, V start);  }
@Test public void testTee() { FluentIterator<Integer> t = fluent(unaryGenerator(0, x -> x + 1)); List<FluentIterator<Integer>> forks = t.tee(5); BinaryOperator<Integer> acc = (a, b) -> a + b; for (FluentIterator<Integer> f : forks) { int sum = f.limit(10).reduce(acc); assertEquals(45, sum); } t = fluent(unaryGenerator(0, x -> x + 1)); forks = t.limit(10).tee(5); for (FluentIterator<Integer> f : forks) { int sum = f.reduce(acc); assertEquals(45, sum); } }