package plp.collection; /** * A fonctional kind of list "a la Scheme". * car denotes the first element of a list, * cdr the list minus the first element. */ public class SList { /* This version does not use tail recursive methods.*/ private Object car; private SList cdr; /** * The empty list. */ public static final SList EMPTY = new SList(); private SList() { } /** * A cdr cannot be null (null cannot be a SList, even to represent * the empty list). */ public SList(Object car, SList cdr) { if (cdr == null) { throw new Error("Cannot use null as cdr"); } this.car = car; this.cdr = cdr; } /** Test if the list is EMPTY. */ public boolean empty() { return this == EMPTY; } private void checkNonEmpty(String msg) { if (empty()) { throw new Error(msg); } } /** * Cannot be used on EMPTY SList. */ public Object car() { checkNonEmpty("Calling car() on empty list"); return car; } /** * Cannot be used on EMPTY SList. */ public SList cdr() { checkNonEmpty("Calling cdr() on empty list"); return cdr; } public int length() { return empty()? 0 : 1 + cdr().length(); } public SList append(SList l2) { return empty()? l2 : new SList(car(), cdr().append(l2)); } public SList reverse() { return empty() ? this : cdr().reverse().append(new SList(car(), EMPTY)); } public String toString() { String s = "("; if (!empty()) { s += car(); for (SList l = this.cdr(); !l.empty(); l = l.cdr()) { s += " " + l.car(); } } s += ")"; return s; } }