FluentIterator implements ImmutableIterator<T> { @SuppressWarnings("unchecked") public FluentIterator<T> concat(Iterator... ts) { Iterator<T>[] tmp = Arrays.copyOf(ts, ts.length + 1); tmp[0] = this; System.arraycopy(ts, 0, tmp, 1, ts.length); return fluent(Iterators.concat(tmp)); } 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 testConcat() { Iterator<Integer> r = fluent(unaryGenerator(1, x -> x + 1)).limit(5); Iterator<Integer> s = fluent(unaryGenerator(6, x -> x + 1)).limit(5); Iterator<Integer> t = fluent(unaryGenerator(11, x -> x + 1)).limit(5); t = concat(s, r, t); BinaryOperator<Integer> f = (a, b) -> a + b; int sum = fluent(t).reduce(f); assertEquals(120, sum); }