package org.codefx.libfx.collection.transform; import java.util.Iterator; import java.util.Objects; import java.util.function.Function; /** * An {@link Iterator} which wraps another iterator and transforms the returned elements from their inner type {@code I} * to an outer type {@code O}. * <p> * The transformation of null elements is fixed to {@code null -> null}. The transformation function specified during * construction does not have to handle null input elements and is not allowed to produce a null result. * * @param <I> * the inner type, i.e. the type of the elements returned by the wrapped/inner iterator * @param <O> * the outer type, i.e. the type of elements returned by this iterator */ public final class TransformingIterator<I, O> extends AbstractTransformingIterator<I, O> { private final Iterator<? extends I> innerIterator; private final Function<? super I, ? extends O> transformToOuter; /** * Creates a new iterator. * <p> * If the specified iterator is used by any other instance, the behavior is undefined. The specified transform * function will not be called with null elements and is not allowed to return null. * * @param innerIterator * the wrapped/inner iterator * @param transformToOuter * transforms elements from the inner type {@code I} to the outer type {@code O} */ public TransformingIterator( Iterator<? extends I> innerIterator, Function<? super I, ? extends O> transformToOuter) { Objects.requireNonNull(innerIterator, "The argument 'innerIterator' must not be null."); Objects.requireNonNull(transformToOuter, "The argument 'transformToOuter' must not be null."); this.innerIterator = innerIterator; this.transformToOuter = transformToOuter; } @Override protected Iterator<? extends I> getInnerIterator() { return innerIterator; } @Override protected O transformToOuter(I innerElement) { if (innerElement == null) return null; O outerElement = transformToOuter.apply(innerElement); Objects.requireNonNull(outerElement, "The transformation must not create null instances."); return outerElement; } }