package au.id.zancanaro; import java.util.Iterator; import java.util.function.Function; public final class Iterators { public static RangeIterator rangeIterator(int countTo, Function fn) { return new RangeIterator(countTo, fn); } private static class RangeIterator implements Iterator { private final Function action; private final int countTo; private int index = 0; public RangeIterator(int countTo, Function action) { this.countTo = countTo; this.action = action; } @Override public boolean hasNext() { return index < countTo; } @Override public T next() { return action.apply(index++); } } public static FlattenIterator flatten(Iterator> iterators) { return new FlattenIterator<>(iterators); } public static class FlattenIterator implements Iterator { private Iterator current; private Iterator> iterators; public FlattenIterator(Iterator> iterators) { this.current = Iterators.emptyIterator(); this.iterators = iterators; } private Iterator getCurrent() { while (!current.hasNext() && iterators.hasNext()) { current = iterators.next(); } return current; } @Override public boolean hasNext() { return getCurrent().hasNext(); } @Override public T next() { return getCurrent().next(); } } public static ConcatIterator concat(Iterator left, Iterator right) { return new ConcatIterator<>(left, right); } public static class ConcatIterator implements Iterator { private final Iterator left; private final Iterator right; public ConcatIterator(Iterator left, Iterator right) { this.left = left; this.right = right; } @Override public boolean hasNext() { return left.hasNext() || right.hasNext(); } @Override public T next() { if (left.hasNext()) { return left.next(); } else { return right.next(); } } } public static EmptyIterator emptyIterator() { return new EmptyIterator<>(); } public static class EmptyIterator implements Iterator { @Override public boolean hasNext() { return false; } @Override public T next() { return null; } } public static MappingIterator mappingIterator(Function f, Iterator iterator) { return new MappingIterator<>(f, iterator); } private static class MappingIterator implements Iterator { private final Function mapping; private final Iterator iterator; public MappingIterator(Function mapping, Iterator iterator) { this.mapping = mapping; this.iterator = iterator; } @Override public boolean hasNext() { return iterator.hasNext(); } @Override public R next() { return mapping.apply(iterator.next()); } } }