IteratorApplicator.java

/***************************************************************************
   Copyright 2009 Emily Estes

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
***************************************************************************/
package net.metanotion.functor;


import java.util.Iterator;

/** This class implements a "mapped" iterator. Given an iterator and a block, this class
provides a new iterator that, on demand, applies the block to the results of the backing
iterator, thus map'ing the block over the iterator.
	@param <E> The type of elements produced by this iterator.
	@param <E1> The type of elements provided by the iterator this instance wraps.
*/
public final class IteratorApplicator<E,E1> implements Iterator<E> {
	private final Iterator<E1> i;
	private final Block<E1,E> a;

	/** Take a list and produce an iterator from it, applying the provided block to it's elements.
		@param list The list we're going to produce an iterator from.
		@param a The function we're going to map over the list.
	*/
	public IteratorApplicator(final Iterable<E1> list, final Block<E1,E> a) { this(list.iterator(), a); }

	/** Take an iterator and produce a new iterator from it, applying the provided block to it's elements.
		@param i The iterator we're going to produce an iterator from.
		@param a The function we're going to map over the iterator.
	*/
	public IteratorApplicator(final Iterator<E1> i, final Block<E1,E> a) {
		this.i = i;
		this.a = a;
	}

	@Override public boolean hasNext() { return i.hasNext(); }

	@Override public E next() {
		final E1 e = i.next();
		try {
			return a.eval(e);
		} catch (final Exception ex) { throw new RuntimeException(ex); }
	}

	@Override public void remove() { throw new UnsupportedOperationException(); }
}