FluentIterator implements ImmutableIterator<T> { public T reduce(BinaryOperator<T> f) { return Iterators.reduce(this, 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 testReduce() { FluentIterator<Integer> t = fluent(repeat(10, 5)); BinaryOperator<Integer> op = (a, b) -> a + b; int sum = t.reduce(op); assertEquals(50, sum); t = fluent(repeat(10, 5)); BinaryOperator<Integer> mul = (a, b) -> a * b; int prod = t.reduce(mul); assertEquals(100000, prod); t = fluent(empty()); prod = t.reduce(mul, 1); assertEquals(1, prod); t = fluent(of(1, 2, 3)); FluentIterator<Integer> s = fluent(of(10, 20, 30, 40, 50)); BiFunction<FluentIterator<Integer>, Integer, FluentIterator<Integer>> f = (z, x) -> z.map(a -> a * x); int result = t.reduce(f, s).reduce(op); assertEquals(900, result); }