package bjc.utils.funcutils; import java.util.*; import java.util.function.*; import bjc.utils.data.*; /** * Utility methods for dealing with iterators. * * @author bjculkin * */ public class IteratorUtils { /** * A chain iterator. This is essentially flatMap in iterator form. * @author bjculkin * * @param * The type of the input values. * * @param * The type of the output values. */ public static class ChainIterator implements Iterator { private Iterator mainItr; private Function> trans; private Iterator curItr; /** * Create a new chain iterator. * * @param mainItr * The main iterator for input. * * @param trans * The transformation to use to produce the outputs. */ public ChainIterator(Iterator mainItr, Function> trans) { this.mainItr = mainItr; this.trans = trans; } @Override public boolean hasNext() { if (curItr != null) { if (curItr.hasNext()) return true; else return mainItr.hasNext(); } return mainItr.hasNext(); } @Override public T2 next() { if (curItr == null || !curItr.hasNext()) { curItr = trans.apply(mainItr.next()); } return curItr.next(); } } /** * Convert an iterator to an iterable. * * @param itr * The iterator to convert. * * @return An iterable that gives back that iterator. */ public static Iterable I(Iterator itr) { return () -> itr; } /** * Convert an iterable to an iterator. * * @param itr * The iterable to convert. * * @return The iterator from that iterable */ public static Iterator I(Iterable itr) { return itr.iterator(); } /** * Convert an array to an iterator. * * @param parms * The array to iterate over. * * @return An iterator over the provided array. */ @SafeVarargs public static Iterator AI(E... parms) { return new ArrayIterator<>(parms); } /** * Create a chain iterator. * * @param itrA * The iterator for input values. * * @param itrB * The transformation for output values. * * @return A chain iterator from the provided values. */ public static Iterator chain(Iterator itrA, Function> itrB) { return new ChainIterator<>(itrA, itrB); } }