import tester.*; import java.util.ArrayList; import java.util.Arrays; // Useful methods for array lists class ALMethods { // EFFECT: swapping the elements at index i and j void swap(ArrayList al, int i, int j) { al.set(j, al.set(i, al.get(j))); } // Sum elements of given traversable. Integer sum(Traversable t) { return sumTraversal(t.getTraversal()); } // We arrived at above code as a generalization of // sum(ArrayList a) below: /* Integer sum(ArrayList al) { return sumTraversal(new ArrTraversal(al)); // Think about this // return this.sumAcc(al, 0); } */ // Sum elements of al // ACCUM: index of elements summed so far. Integer sumAcc(ArrayList al, Integer i) { if (i.equals(al.size())) { return 0; } else { return al.get(i) + this.sumAcc(al, i+1); } } // Count number of elements in traversable. Integer count(Traversable t) { return this.countTraversal(t.getTraversal()); } // Count number of elemenets in traversal Integer countTraversal(Traversal t) { if (t.emptyHuh()) { return 0; } else { return 1+countTraversal(t.getRest()); } } // Sum elements of traversal Integer sumTraversal(Traversal t) { if (t.emptyHuh()) { return -0; } else { return t.getFirst() + sumTraversal(t.getRest()); } } } // Interface of things which can be traversed. interface Traversable { Traversal getTraversal(); } // Represents the ordered Traversal of some data. interface Traversal { // Is it empty Boolean emptyHuh(); // Get the first of this Traversal (a W) W getFirst(); // Get the rest of this Traversal (another Traversal) Traversal getRest(); } // Stacks behave first in, first out (like a stack of plates at the cafeteria). interface Stack extends Traversable { void push(T t); T pop(); T peek(); // Traversal getTraversal(); } // Queues behave last in, first out (like a line of people at the cafeteria). interface Queue extends Traversable { void enqueue(T t); T dequeue(); T peek(); Traversal getTraversal(); } // Represents a traversal of an array list // Index i is current location in al. class ArrTraversal implements Traversal, Traversable { ArrayList al; Integer i; ArrTraversal(ArrayList al) { this(al, 0); } // Private constructor private ArrTraversal(ArrayList al, Integer i) { this.al = al; this.i = i; } // This is a traversal, so just return this. public Traversal getTraversal() { return this; } // Empty when index is at the end. public Boolean emptyHuh() { return i == al.size(); } public T getFirst() { return al.get(i); } public Traversal getRest() { return new ArrTraversal(this.al, this.i+1); } } // Represents a delicious pancake. class Pancake { String topping; Pancake(String topping) { this.topping = topping; } } // Implements a stack with an ArrayList. class ArrStack implements Stack { ArrayList elements; // Construct an empty stack ArrStack() { this.elements = new ArrayList(); } public void push(T t) { this.elements.add(t); } // Produce the last element pushed onto this stack. // EFFECT: remove the last element pushed. public T pop() { return this.elements.remove(this.elements.size()-1); } // Produce the last element pushed onto this stack. public T peek() { return this.elements.get(this.elements.size()-1); } public Traversal getTraversal() { return new ArrTraversal(this.elements); } } // Implements a queue with an ArrayList. class ArrQueue implements Queue { ArrayList elements; ArrQueue() { this.elements = new ArrayList(); } public void enqueue(T t) { this.elements.add(t); } public T dequeue() { return this.elements.remove(0); } public T peek() { return this.elements.get(0); } public Traversal getTraversal() { return new ArrTraversal(this.elements); } } class Examples { ALMethods m = new ALMethods(); void testSwap(Tester t) { ArrayList a = new ArrayList(); a.add("a"); a.add("b"); m.swap(a, 0, 1); ArrayList b = new ArrayList(); b.add("b"); b.add("a"); t.checkExpect(a, b); } void testConstructArrayList(Tester t) { // Some tests for getting to know ArrayLists. ArrayList a = new ArrayList(); a.add("a"); a.add("b"); a.add("c"); ArrayList b = new ArrayList(); b.add("a"); b.add("b"); b.add("c"); ArrayList f = new ArrayList(a); t.checkExpect(a, b); t.checkExpect(a.get(0), "a"); t.checkExpect(a.get(1), "b"); t.checkExpect(a.get(2), "c"); // t.checkExpect(a.get(4), "something"); a.add(1, "d"); t.checkExpect(a.get(0), "a"); t.checkExpect(a.get(1), "d"); t.checkExpect(a.get(2), "b"); t.checkExpect(a.get(3), "c"); a.addAll(b); t.checkExpect(a.get(0), "a"); t.checkExpect(a.get(1), "d"); t.checkExpect(a.get(2), "b"); t.checkExpect(a.get(3), "c"); t.checkExpect(a.get(4), "a"); t.checkExpect(a.get(5), "b"); t.checkExpect(a.get(6), "c"); a.clear(); t.checkExpect(a, new ArrayList()); t.checkExpect(a.contains("a"), false); t.checkExpect(a.isEmpty(), true); a.addAll(b); t.checkExpect(a.contains("c"), true); a.addAll(b); // [a,b,c,a,b,c] t.checkExpect(a.indexOf("c"), 2); t.checkExpect(a.isEmpty(), false); t.checkExpect(a.lastIndexOf("c"), 5); t.checkExpect(a.size(), 6); t.checkExpect(a.remove(5), "c"); // [a,b,c,a,b] t.checkExpect(a.size(), 5); t.checkExpect(a.remove("a"), true); // [b,c,a,b] t.checkExpect(a.get(0), "b"); t.checkExpect(a.containsAll(b), true); //a.removeRange(1,3); // [b,b] t.checkExpect(a.set(1, "d"), "c"); // [b, d, a, b] t.checkExpect(a.get(1), "d"); t.checkExpect(a.containsAll(b), false); a.retainAll(b); // [b, a, b] t.checkExpect(a.size(), 3); t.checkExpect(a.get(1), "a"); ArrayList c = (ArrayList)a.clone(); // [b,a,b] ArrayList d = a; t.checkExpect(c.get(0), "b"); t.checkExpect(d.get(0), "b"); a.add("c"); // [b,a,b,c] t.checkExpect(a.get(3), "c"); t.checkExpect(d.get(3), "c"); t.checkExpect(c.size(), 3); // [b,a,b] } void testClone(Tester t) { ArrayList> a = new ArrayList>(); ArrayList x = new ArrayList(); x.add(1); x.add(2); x.add(3); a.add(x); ArrayList> b = (ArrayList>)a.clone(); x.set(0, 42); t.checkExpect(b.get(0).get(0), 42); } void testSum(Tester t) { ArrayList is = new ArrayList(Arrays.asList(7,3,2)); t.checkExpect(m.sum(new ArrTraversal(is)), 12); t.checkExpect(m.sum(new ArrTraversal(is)), 12); } void testStack(Tester t) { Pancake pb = new Pancake("butter"); Pancake ps = new Pancake("syrup"); Stack notSoShort = new ArrStack(); notSoShort.push(pb); notSoShort.push(ps); t.checkExpect(notSoShort.peek(), ps); t.checkExpect(notSoShort.pop(), ps); t.checkExpect(notSoShort.peek(), pb); t.checkExpect(m.countTraversal(notSoShort.getTraversal()), 1); } void testQueue(Tester t) { Pancake pb = new Pancake("butter"); Pancake ps = new Pancake("syrup"); Queue notSoShort = new ArrQueue(); notSoShort.enqueue(pb); notSoShort.enqueue(ps); t.checkExpect(m.count(notSoShort), 2); t.checkExpect(m.count(notSoShort), 2); t.checkExpect(notSoShort.peek(), pb); t.checkExpect(notSoShort.dequeue(), pb); t.checkExpect(notSoShort.peek(), ps); t.checkExpect(m.count(notSoShort), 1); } }