package highOrder;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * This class implements a mapper. Instances of this class receive a list and
 * apply a certain algorithm on each element of the list, producing a new list.
 * 
 * @author Fernando
 * 
 * @param <A>
 *        the type of the input list.
 * @param <B>
 *        the type of the output list.
 */
public abstract class Mapper<A, B> {

  /**
   * This method must be implemented by each mapper, in order to apply a certain
   * algorithm on the list.
   * 
   * @param e
   *        The element in the list.
   * @return the result of applying the map on e.
   */
  public abstract B apply(A e);

  /**
   * This method runs over every element on the list, applying the algorithm.
   * 
   * @param l
   *        The target list
   * @return a new list with the results of the mapping.
   */
  public final List<B> map(final List<A> l) {
    List<B> retList = new LinkedList<B>();
    Iterator<A> it = l.iterator();
    while (it.hasNext()) {
      retList.add(apply(it.next()));
    }
    return retList;
  }
}
