// file: SequenceGenerator.java // author: Robert Keller // purpose: Illustrate Enumeration "on-the-fly" import java.util.*; /** * A SequenceGenerator is an Enumeration based on 3 functions: * output is applied to current to create the next element * update is applied to current to produce the next value of current * stopper is applied to current to know when to stop * current is initialized in the constructor */ class SequenceGenerator implements Enumeration { Object current; // the current state of the generator Function1 output; // the output function: current ==> result Function1 update; // the update function: current ==> current Function1 stopper; // the stopper function: current ==> Boolean /** Construct a SequenceGenerator. */ SequenceGenerator(Object initial, Function1 _output, Function1 _update, Function1 _stopper) { current = initial; output = _output; update = _update; stopper = _stopper; } /** Produce the next element in the sequence. */ public Object nextElement() { Object result = output.apply(current); current = update.apply(current); return result; } /** Indicate whether there are more elements in the sequence. */ public boolean hasMoreElements() { return !((Boolean)stopper.apply(current)).booleanValue(); } public static void main(String arg[]) { Enumeration E = new SequenceGenerator(new Integer(0), new Outputter(), new Updater(), new Stopper(100)); while( E.hasMoreElements() ) { System.out.println(E.nextElement()); } } } /** a sample output function object */ class Outputter implements Function1 { /** Apply this function to an argument to get the output value. */ public Object apply(Object arg) { long value = ((Number)arg).longValue(); return new Long(value * value); } } /** a sample update function object */ class Updater implements Function1 { /** Apply this function to an argument to get the next value of current. */ public Object apply(Object arg) { long value = ((Number)arg).longValue(); return new Long(value + 2); } } /** a sample stopper function object */ class Stopper implements Function1 { long limit; /** Create a stopper function based on a limit */ Stopper(long _limit) { limit = _limit; } /** Apply this function to an argument to determine whether to stop. */ public Object apply(Object arg) { long value = ((Number)arg).longValue(); return new Boolean(value > limit); } }