Package com.googlecode.totallylazy

Source Code of com.googlecode.totallylazy.Iterators

package com.googlecode.totallylazy;

import com.googlecode.totallylazy.collections.ImmutableList;
import com.googlecode.totallylazy.iterators.FilterIterator;
import com.googlecode.totallylazy.iterators.FlattenIterator;
import com.googlecode.totallylazy.iterators.InitIterator;
import com.googlecode.totallylazy.iterators.IterateIterator;
import com.googlecode.totallylazy.iterators.MapIterator;
import com.googlecode.totallylazy.iterators.PartitionIterator;
import com.googlecode.totallylazy.iterators.PeekingIterator;
import com.googlecode.totallylazy.iterators.RangerIterator;
import com.googlecode.totallylazy.iterators.RepeatIterator;
import com.googlecode.totallylazy.iterators.TakeWhileIterator;
import com.googlecode.totallylazy.iterators.UnfoldRightIterator;
import com.googlecode.totallylazy.predicates.LogicalPredicate;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.concurrent.Callable;

import static com.googlecode.totallylazy.Callables.nullGuard;
import static com.googlecode.totallylazy.Callables.returns;
import static com.googlecode.totallylazy.Callers.call;
import static com.googlecode.totallylazy.Option.none;
import static com.googlecode.totallylazy.Option.some;
import static com.googlecode.totallylazy.Predicates.instanceOf;
import static com.googlecode.totallylazy.Predicates.is;
import static com.googlecode.totallylazy.Predicates.not;
import static com.googlecode.totallylazy.Predicates.onlyOnce;
import static com.googlecode.totallylazy.Predicates.whileTrue;
import static com.googlecode.totallylazy.Sequences.one;
import static com.googlecode.totallylazy.Sequences.sequence;
import static com.googlecode.totallylazy.numbers.Numbers.increment;

public class Iterators {
    public static boolean equalsTo(Iterator<?> a, Iterator<?> b) {
        while (a.hasNext() && b.hasNext()) {
            Object aValue = a.next();
            Object bValue = b.next();

            if (aValue == bValue) {
                continue;
            }

            if (aValue == null || !aValue.equals(bValue)) {
                return false;
            }
        }
        return !(a.hasNext() || b.hasNext());
    }

    public static <T> void each(final Iterator<? extends T> iterator, final Callable1<? super T, ?> runnable) {
        forEach(iterator, runnable);
    }

    public static <T> void forEach(final Iterator<? extends T> iterator, final Callable1<? super T, ?> runnable) {
        while (iterator.hasNext()) {
            Callers.call(runnable, iterator.next());
        }
    }

    public static <T, S> Iterator<S> map(final Iterator<? extends T> iterator, final Callable1<? super T, ? extends S> callable) {
        return new MapIterator<T, S>(iterator, callable);
    }

    public static <T, S> Iterator<S> flatMap(final Iterator<? extends T> iterator, final Callable1<? super T, ? extends Iterable<? extends S>> callable) {
        return flattenIterable(map(iterator, callable));
    }

    public static <T> Iterator<T> filter(final Iterator<? extends T> iterator, final Predicate<? super T> predicate) {
        return new FilterIterator<T>(iterator, predicate);
    }

    public static <T> Iterator<T> iterate(final Callable1<? super T, ? extends T> callable, final T t) {
        return new IterateIterator<T>(nullGuard(callable), t);
    }

    public static <T> T head(final Iterator<? extends T> iterator) {
        if (iterator.hasNext()) {
            return iterator.next();
        }
        throw new NoSuchElementException();
    }

    public static <T> Option<T> headOption(final Iterator<? extends T> iterator) {
        return iterator.hasNext() ? some(iterator.next()) : Option.<T>none();
    }

    public static <T> T last(final Iterator<? extends T> iterator) {
        return head(reverse(iterator));
    }

    public static <T> Option<T> lastOption(final Iterator<? extends T> iterator) {
        return headOption(reverse(iterator));
    }

    public static <T> Iterator<T> tail(final Iterator<? extends T> iterator) {
        if (iterator.hasNext()) {
            iterator.next();
            return new PeekingIterator<T>(iterator);
        }
        throw new NoSuchElementException();
    }

    public static <T> Iterator<T> init(final Iterator<? extends T> iterator) {
        return new InitIterator<T>(iterator);
    }

    public static <T, S> S fold(final Iterator<? extends T> iterator, final S seed, final Callable2<? super S, ? super T, ? extends S> callable) {
        return foldLeft(iterator, seed, callable);
    }

    public static <T, S> S foldLeft(final Iterator<? extends T> iterator, final S seed, final Callable2<? super S, ? super T, ? extends S> callable) {
        S accumulator = seed;
        while (iterator.hasNext()) {
            accumulator = call(callable, accumulator, iterator.next());
        }
        return accumulator;
    }

    public static <T, S> S foldRight(final Iterator<? extends T> iterator, final S seed, final Callable2<? super T, ? super S, ? extends S> callable) {
        Iterator<T> reversed = reverse(iterator);
        S accumilator = seed;
        while (reversed.hasNext()) {
            accumilator = call(callable, reversed.next(), accumilator);
        }
        return accumilator;
    }

    public static <T> Iterator<T> reverse(Iterator<? extends T> iterator) {
        return ImmutableList.constructors.reverse(iterator).iterator();
    }

    public static <T, S> S foldRight(final Iterator<? extends T> iterator, final S seed, final Callable1<? super Pair<T, S>, ? extends S> callable) {
        if (!iterator.hasNext()) return seed;
        return Callers.call(callable, Pair.pair(returns(head(iterator)), new Function<S>() {
            @Override
            public S call() throws Exception {
                return foldRight(iterator, seed, callable);
            }
        }));
    }

    public static <T, S> S reduce(final Iterator<? extends T> iterator, final Callable2<? super S, ? super T, ? extends S> callable) {
        return reduceLeft(iterator, callable);
    }

    public static <T, S> S reduceLeft(final Iterator<? extends T> iterator, final Callable2<? super S, ? super T, ? extends S> callable) {
        return foldLeft(iterator, seed(iterator, callable), callable);
    }

    private static <T, S> S seed(Iterator<? extends T> iterator, Callable2<? super S, ? super T, ? extends S> callable) {
        if(callable instanceof Identity) return Unchecked.<Identity<S>>cast(callable).identity();
        return Unchecked.<S>cast(iterator.next());
    }

    public static <T, S> S reduceRight(final Iterator<? extends T> iterator, final Callable2<? super T, ? super S, ? extends S> callable) {
        return foldRight(iterator, Unchecked.<S>cast(iterator.next()), callable);
    }

    public static <T, S> S reduceRight(final Iterator<? extends T> iterator, final Callable1<? super Pair<T, S>, ? extends S> callable) {
        return foldRight(iterator, Unchecked.<S>cast(iterator.next()), callable);
    }

    public static String toString(final Iterator<?> iterator, final String separator) {
        return toString(iterator, "", separator, "");
    }

    public static String toString(final Iterator<?> iterator, final String start, final String separator, final String end) {
        StringBuilder builder = new StringBuilder();
        builder.append(start);
        if (iterator.hasNext()) builder.append(iterator.next());
        while (iterator.hasNext()) {
            builder.append(separator);
            builder.append(iterator.next());
        }
        builder.append(end);
        return builder.toString();
    }

    public static <T> List<T> toList(final Iterator<? extends T> iterator) {
        final List<T> result = new ArrayList<T>();
        while (iterator.hasNext()) {
            result.add(iterator.next());
        }
        return result;
    }

    public static <T> Deque<T> toDeque(final Iterator<? extends T> iterator) {
        final Deque<T> result = new ArrayDeque<T>();
        while (iterator.hasNext()) {
            result.add(iterator.next());
        }
        return result;
    }

    public static <T> Iterator<T> repeat(final Callable<? extends T> callable) {
        return new RepeatIterator<T>(callable);
    }

    public static <T> Iterator<T> repeat(final T item) {
        return new RepeatIterator<T>(returns(item));
    }

    public static Iterator<Number> range(final Number start) {
        return iterate(increment, start);
    }

    public static Iterator<Number> range(final Number start, final Number end) {
        return new RangerIterator(start, end);
    }

    public static Iterator<Number> range(final Number start, final Number end, final Number step) {
        return new RangerIterator(start, end, step);
    }

    public static <T> Iterator<T> remove(final Iterator<? extends T> iterator, final T t) {
        return filter(iterator, not(onlyOnce(is(t))));
    }

    public static <T> Iterator<T> take(final Iterator<? extends T> iterator, final int count) {
        return takeWhile(iterator, Predicates.countTo(count));
    }

    public static <T> Iterator<T> takeWhile(final Iterator<? extends T> iterator, final Predicate<? super T> predicate) {
        return new TakeWhileIterator<T>(iterator, predicate);
    }

    public static <T> Iterator<T> drop(final Iterator<? extends T> iterator, final int count) {
        return dropWhile(iterator, Predicates.countTo(count));
    }

    public static <T> Iterator<T> dropWhile(final Iterator<? extends T> iterator, final Predicate<? super T> predicate) {
        return filter(iterator, not(whileTrue(predicate)));
    }

    public static <T> boolean forAll(final Iterator<? extends T> iterator, final Predicate<? super T> predicate) {
        while (iterator.hasNext()) {
            if (!predicate.matches(iterator.next())) {
                return false;
            }
        }
        return true;
    }

    public static <T> boolean contains(final Iterator<? extends T> iterator, final T t) {
        return exists(iterator, is(t));
    }

    public static <T> boolean exists(final Iterator<? extends T> iterator, final Predicate<? super T> predicate) {
        while (iterator.hasNext()) {
            boolean result = predicate.matches(iterator.next());
            if (result) {
                return true;
            }
        }
        return false;
    }

    public static <T> Option<T> find(final Iterator<? extends T> iterator, final Predicate<? super T> predicate) {
        while (iterator.hasNext()) {
            T item = iterator.next();
            boolean result = predicate.matches(item);
            if (result) {
                return some(item);
            }
        }
        return none();
    }

    public static <T, S> Option<S> tryPick(final Iterator<? extends T> iterator, final Callable1<? super T, ? extends Option<? extends S>> callable) {
        while (iterator.hasNext()) {
            T item = iterator.next();
            Option<S> result = Unchecked.cast(call(callable, item));
            if (!result.isEmpty()) {
                return result;
            }
        }
        return none();
    }

    public static <T, S> S pick(final Iterator<? extends T> iterator, final Callable1<? super T, ? extends Option<? extends S>> callable) {
        return tryPick(iterator, callable).get();
    }

    public static <T> Iterator<T> add(final Iterator<? extends T> iterator, final T t) {
        return join(iterator, sequence(t).iterator());
    }

    public static <T> Iterator<T> join(final Iterator<? extends T> first, final Iterator<? extends T> second) {
        return join(sequence(first, second));
    }

    public static <T> Iterator<T> join(final Iterator<? extends T> first, final Iterator<? extends T> second, final Iterator<? extends T> third) {
        return join(sequence(first, second, third));
    }

    public static <T> Iterator<T> join(final Iterator<? extends T> first, final Iterator<? extends T> second, final Iterator<? extends T> third, final Iterator<? extends T> fourth) {
        return join(sequence(first, second, third, fourth));
    }

    public static <T> Iterator<T> join(final Iterator<? extends T> first, final Iterator<? extends T> second, final Iterator<? extends T> third, final Iterator<? extends T> fourth, final Iterator<? extends T> fifth) {
        return join(sequence(first, second, third, fourth, fifth));
    }

    public static <T> Iterator<T> join(final Iterator<? extends T>... iterators) {
        return join(sequence(iterators));
    }

    public static <T> Iterator<T> join(final Iterable<? extends Iterator<? extends T>> iterable) {
        return flatten(iterable.iterator());
    }

    public static <T> Iterator<T> cons(final T t, final Iterator<? extends T> iterator) {
        return join(one(t).iterator(), iterator);
    }

    public static <T, S> Iterator<S> safeCast(final Iterator<? extends T> iterator, final Class<? extends S> aClass) {
        return map(filter(iterator, instanceOf(aClass)), Callables.cast(aClass));
    }

    public static <T, S> Iterator<S> unsafeCast(final Iterator<? extends T> iterator) {
        return map(iterator, Callables.<T, S>cast());
    }

    public static <T> int size(final Iterator<? extends T> iterator) {
        int count = 0;
        while (iterator.hasNext()) {
            iterator.next();
            count++;
        }
        return count;
    }

    public static <T> Number number(final Iterator<? extends T> iterator) {
        Number count = 0;
        while (iterator.hasNext()) {
            iterator.next();
            count = increment(count);
        }
        return count;
    }

    public static <T> Pair<Sequence<T>, Sequence<T>> partition(final Iterator<? extends T> iterator, final Predicate<? super T> predicate) {
        final Queue<T> matchedQueue = new ArrayDeque<T>();
        final Queue<T> unmatchedUnmatched = new ArrayDeque<T>();
        return Pair.pair(Sequences.memorise(new PartitionIterator<T>(iterator, predicate, matchedQueue, unmatchedUnmatched)),
                Sequences.memorise(new PartitionIterator<T>(iterator, Predicates.<T>not(predicate), unmatchedUnmatched, matchedQueue)));
    }

    public static <T> Pair<Sequence<T>, Sequence<T>> splitAt(final Iterator<? extends T> iterator, final Number index) {
        return partition(iterator, Predicates.countTo(index));
    }

    public static <T> Pair<Sequence<T>, Sequence<T>> splitWhen(final Iterator<? extends T> iterator, final Predicate<? super T> predicate) {
        Pair<Sequence<T>, Sequence<T>> partition = breakOn(iterator, predicate);
        return Pair.pair(partition.first(), partition.second().isEmpty() ? Sequences.<T>empty() : partition.second().tail());
    }

    public static <T> Pair<Sequence<T>, Sequence<T>> splitOn(final Iterator<? extends T> iterator, final T instance) {
        return splitWhen(iterator, is(instance));
    }

    public static <T> Pair<Sequence<T>, Sequence<T>> span(final Iterator<? extends T> iterator, final Predicate<? super T> predicate) {
        return partition(iterator, whileTrue(predicate));
    }

    public static <T> Pair<Sequence<T>, Sequence<T>> breakOn(final Iterator<? extends T> iterator, final Predicate<? super T> predicate) {
        return partition(iterator, whileTrue(Predicates.<T>not(predicate)));
    }

    public static <T, Key> Sequence<Group<Key, T>> groupBy(final Iterator<? extends T> iterator, final Callable1<? super T, ? extends Key> callable) {
        return Maps.entries(Maps.multiMap(iterator, callable)).map(new Callable1<Map.Entry<Key, List<T>>, Group<Key, T>>() {
            @Override
            public Group<Key, T> call(Map.Entry<Key, List<T>> entry) throws Exception {
                return new Group<Key, T>(entry.getKey(), entry.getValue());
            }
        });
    }

    public static <T> LogicalPredicate<Iterator<T>> hasNext() {
        return new LogicalPredicate<Iterator<T>>() {
            public boolean matches(Iterator<T> iterator) {
                return iterator.hasNext();
            }
        };
    }

    public static <T> Function1<Iterator<T>, T> next() {
        return new Function1<Iterator<T>, T>() {
            public T call(Iterator<T> iterator) throws Exception {
                return iterator.next();
            }
        };
    }

    public static <T> Iterator<T> flatten(final Iterator<? extends Iterator<? extends T>> iterator) {
        return new FlattenIterator<T>(iterator);
    }

    public static <T> Iterator<T> flattenIterable(final Iterator<? extends Iterable<? extends T>> iterator) {
        Iterator<Iterable<T>> noWildCards = unsafeCast(iterator);
        return flatten(map(noWildCards, Callables.<T>asIterator()));
    }

    public static <T> Iterator<T> interruptable(final Iterator<? extends T> iterator) {
        return map(iterator, Callables.<T>returnArgument().interruptable());
    }

    public static <A, B> Iterator<A> unfoldRight(Callable1<? super B, ? extends Option<? extends Pair<? extends A, ? extends B>>> callable, B seed) {
        return new UnfoldRightIterator<A, B>(callable, seed);
    }
}
TOP

Related Classes of com.googlecode.totallylazy.Iterators

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.