// Immutable linked lists of Objects // Use the name "ObjectList" rather than "List" to avoid confusion with "List" in the AWT import java.util.Vector; public class ObjectList { // Instance variables private Object head; private ObjectList tail; private boolean empty; // Constructor method: private ObjectList () { this.empty = true; } private ObjectList (Object head, ObjectList tail) { this.head = head; this.tail = tail; this.empty = false; } // Instance methods: private boolean isEmpty() { return empty; } private ObjectList prepend(Object n) { return new ObjectList (n, this); } private Object head () { if (empty) { throw new RuntimeException("Attempt to get the head of an empty ObjectList"); } else { return head; } } private ObjectList tail() { if (empty) { throw new RuntimeException("Attempt to get the tail of an empty ObjectList"); } else { return tail; } } public String toString () { if (empty) { return "[]"; } else { StringBuffer sb = new StringBuffer(); sb.append("["); sb.append(head); ObjectList toDo = tail; while (! toDo.empty) { sb.append(","); sb.append(toDo.head); toDo = toDo.tail; } sb.append("]"); return sb.toString(); } } public boolean equals (Object x) { if (x instanceof ObjectList) { ObjectList L = (ObjectList) x; if (empty) { return L.isEmpty(); } else if (L.isEmpty()) { return false; } else { return this.head().equals(L.head()) && this.tail().equals(L.tail()); } } else { return false; } } public static void prettyPrint1 (ObjectList L) { // Only expand outermost list to multiple lines. // Useful for printing list of lists. ppIndent1(L); } private static void ppIndent1 (ObjectList L) { if (isEmpty(L)) { System.out.print("[]"); } else { System.out.print("["); for (ObjectList elts = L; ! isEmpty(elts); elts = tail(elts)) { System.out.print(head(elts).toString()); if (isEmpty(tail(elts))) { System.out.println(); } else { System.out.println(","); } System.out.print(" "); } System.out.println("]"); } } // Class Methods: public static ObjectList empty() { return new ObjectList(); } public static boolean isEmpty(ObjectList L) { return L.empty; } public static ObjectList prepend(Object n, ObjectList L) { return new ObjectList(n, L); } public static Object head(ObjectList L) { return L.head(); } public static ObjectList tail(ObjectList L) { return L.tail(); } public static String toString (ObjectList L) { return L.toString(); } public static boolean equals (ObjectList L1, ObjectList L2) { return L1.equals(L2); } public static ObjectList fromString (String s) { return fromVector(VectorOps.fromStringHelper(s,'[',']')); } public static ObjectList fromVector (Vector v) { ObjectList result = empty(); for (int i = v.size() - 1; i >=0; i--) { result = prepend(v.get(i), result); } return result; } public static ObjectList fromArray(Object [] a) { ObjectList result = empty(); for (int i = a.length - 1; i >=0; i--) { result = prepend(a[i], result); } return result; } public static void main (String [] args) { if (args.length == 2 && args[0].equals("fromString")) { System.out.println(fromString(args[1])); } else { System.out.println("unrecognized option"); } } }