public interface IList<E> { public abstract <R,P> R execute(IListAlgo<? super E, R, P> algo, P ... inp); }
public interface IMTList<E> extends IList<E> { }
public interface INEList<E> extends IList<E> { public abstract E getFirst(); public abstract IList<? extends E> getRest(); }
/** * A visitor to (algorithm on) an IList<T> where T is a subclass of E * Also parameterized by it return type R and input parameter type P. */ public interface IListAlgo<E,R,P> { public abstract R emptyCase(IMTList<? extends E> host, P ... inp); public abstract R nonEmptyCase(INEList<? extends E> host, P ... inp); }
public interface IListFactory<E> { public abstract IMTList<E> makeEmptyList(); public abstract INEList<E> makeNEList(E first, IList<? extends E> rest); }
public class ToStringAlgo implements IListAlgo<Object, String, Object> { public static final ToStringAlgo Singleton = new ToStringAlgo(); private ToStringAlgo() { } /** * Returns "()". */ public String emptyCase(IMTList<? extends Object> host, Object ... inp) { return "()"; } /** * Passes "(" + first to the rest of IList and asks for help to complete the computation. */ public String nonEmptyCase(INEList<? extends Object> host, Object ... inp) { return host.getRest().execute(ToStringHelper.Singleton, "(" + host.getFirst()); } } /** * Helps ToStringAlgo compute the String representation of the rest of the list. */ class ToStringHelper implements IListAlgo<Object, String, String> { public static final ToStringHelper Singleton = new ToStringHelper(); private ToStringHelper() { } /** * Returns the accumulated String + ")". * At end of list: done! */ public String emptyCase(IMTList<? extends Object> host, String ... acc) { return acc[0] + ")"; } /** * Continues accumulating the String representation by appending ", " + first to acc * and recur! */ public String nonEmptyCase(INEList<? extends Object> host, String ... acc) { return host.getRest().execute(this, acc[0] + ", " + host.getFirst()); } }
/** * Copies an IList<T> using the supplied IListFactory<T> */ public class CopyList2<T> implements IListAlgo<T,IList<T>, Object> { private IListFactory<T> fac; public CopyList2(IListFactory<T> fac) { this.fac = fac; } public IMTList<T> emptyCase(IMTList<? extends T> host, Object ... nu) { return fac.makeEmptyList(); } public INEList<T> nonEmptyCase(INEList<? extends T> host, Object ... nu) { return fac.makeNEList( host.getFirst(), host.getRest().execute(this)); } }
/** * Copies an IList<T> using the an IListFactory<T> supplied as an input parameter. */ public class CopyList3<T> implements IListAlgo<T,IList<T>, IListFactory<?>> { public IMTList<T> emptyCase(IMTList<? extends T> host, IListFactory<?> ... fac) { return ((IListFactory<T>)fac[0]).makeEmptyList(); // Generates "unchecked cast" warning } public INEList<T> nonEmptyCase(INEList<? extends T> host, IListFactory<?> ... fac) { return ((IListFactory<T>)fac[0]).makeNEList( host.getFirst(), host.getRest().execute(this, fac)); // Generates "unchecked cast" warning } }
Last Revised Wednesday, 21-Feb-2007 13:10:57 CST
©2005 Stephen Wong and Dung Nguyen