Iterators { public static <T, K> ImmutableIterator<T> keepLast(Iterator<T> iterator, Function<? super T, ? extends K> key) { return new SkipDuplicates<>(iterator, key, false); } private  Iterators(); static ImmutableIterator<T> of(T... xs); static ImmutableIterator<T> asIterator(Iterable<T> xs); static ImmutableIterator<T> repeat(T x, int n); static InfiniteIterator<T> repeat(T x); static ImmutableIterator<T> empty(); static ImmutableIterator<T> of(T element); static InfiniteIterator<T> generate(Supplier<T> sp); static ImmutableIterator<T> concat(Iterator<T>... ts); static InfiniteIterator<T> cycle(T... xs); static List<T> take(Iterator<T> t, int n); static List<T> takeAll(Iterator<T> t); static ImmutableIterator<T> limit(Iterator<T> t, int n); static ImmutableIterator<T> reverse(List<T> xs); static ImmutableIterator<T> peek(Iterator<T> t, Consumer<? super T> cs); static ImmutableIterator<T> map(Iterator<F> from, Function<? super F, ? extends T> mapper); static ImmutableIterator<T> map(Iterator<T> first,
                                               Iterator<T> second,
                                               BinaryOperator<T> mapper); static T reduce(Iterator<T> t, BinaryOperator<T> acc); static V reduce(Iterator<T> t, BiFunction<V, T, V> acc, V seed); static ImmutableIterator<T> merge(List<Iterator<T>> iterators, boolean weak); static List<ImmutableIterator<T>> tee(Iterator<T> from, int forks); static ImmutableIterator<List<T>> zip(List<Iterator<T>> ts); static ImmutableIterator<List<T>> zip(List<Iterator<T>> ts, boolean weak); static List<ImmutableIterator<T>> unzip(Iterator<List<T>> zippedIterator); static ImmutableIterator<Pair<A, B>> zip(Pair<Iterator<A>, Iterator<B>> iterators, boolean weak); static ImmutableIterator<T> skipDuplicates(Iterator<T> iterator, Function<? super T, ? extends K> key); static ImmutableIterator<T> keepFirst(Iterator<T> iterator, Function<? super T, ? extends K> key); static ImmutableIterator<T> keepLast(Iterator<T> iterator, Function<? super T, ? extends K> key); static ImmutableIterator<T> skipDuplicates(Iterator<T> iterator); static ImmutableIterator<T> keepFirst(Iterator<T> iterator); static ImmutableIterator<T> keepLast(Iterator<T> iterator); static ImmutableIterator<List<T>> groupBy(Iterator<T> iterator, Function<T, V> key); static ImmutableIterator<List<T>> groupBy(Iterator<T> iterator); static boolean weakEquals(Iterator<? extends T> first, Iterator<? extends T> second, int n); static boolean any(Iterator<T> t, Predicate<? super T> p); static boolean any(Iterable<T> xs, Predicate<? super T> p); static boolean all(Iterable<T> xs, Predicate<? super T> p); static boolean all(Iterator<T> t, Predicate<? super T> p); static ImmutableIterator filter(Iterable<T> xs, Predicate<? super T> p); static ImmutableIterator filter(Iterator<T> t, Predicate<? super T> p); static InfiniteIterator<T> unaryGenerator(T v, UnaryOperator<T> f); static InfiniteIterator<T> binaryGenerator(T v, T w, BinaryOperator<T> f);  }
@Test public void testKeepLast() { Iterator<Integer> s = empty(); BiFunction<Integer, Integer, Integer> acc = (a, b) -> a + b; int sum = reduce(keepLast(s), acc, 0); assertEquals(0, sum); s = repeat(17, 100); BinaryOperator<Integer> op = (a, b) -> a + b; sum = reduce(keepLast(s), op); assertEquals(17, sum); Iterator<Integer> r = concat(repeat(17, 100), repeat(18, 100)); sum = reduce(keepLast(r), op); assertEquals(35, sum); r = concat(repeat(7, 100), repeat(10, 100)); List<Integer> xs = takeAll(keepLast(r, x -> x % 3)); assertEquals(1, xs.size()); assertEquals((Integer) 10, xs.get(0)); xs = takeAll(keepLast(of(2))); assertEquals(1, xs.size()); xs = takeAll(keepLast(of(2, 3))); assertEquals(2, xs.size()); }