package plp.collection; import java.util.Iterator; import java.util.NoSuchElementException; import plp.util.Predicate; /** * A list with cursor. * Elements are inserted or removed following the position of the cursor. * This version implements a position facility and an iterator. */ public class CList { private int size; private Cell cursor; private Cell first; private Cell end; public CList() { size = 0; first = new Cell(); end = new Cell(first, null); cursor = first; } public int size() { return size; } public boolean empty() { return size == 0; } public void insert(Object o) { cursor = new Cell(cursor, o, cursor.next()); size ++; } private void checkNotEnd() throws InvalidPositionException { if (atEnd()) throw new InvalidPositionException(); } private void checkNotFirst() throws InvalidPositionException { if (atFirst()) throw new InvalidPositionException(); } public void replace(Object o) throws InvalidPositionException { checkNotEnd(); cursor.next().setData(o); } public void remove() throws InvalidPositionException { checkNotEnd(); cursor.next().remove(); size --; } public void goFirst() { cursor = first; } public void goEnd() { cursor = end.prev(); } public void goTo(Position pos) throws InvalidPositionException { if (!pos.isValid()) throw new InvalidPositionException(); cursor = (Cell)pos; } public Position getPosition() { return cursor; } public boolean atFirst() { return cursor == first; } public boolean atEnd() { return cursor == end.prev(); } public void forward() throws InvalidPositionException { checkNotEnd(); cursor = cursor.next(); } public void backward() throws InvalidPositionException { checkNotFirst(); cursor = cursor.prev(); } public Object get() throws InvalidPositionException { checkNotEnd(); return cursor.next().data(); } private class PredicateTrue implements Predicate { public boolean predicate(Object o) { return true; } } public Iterator iterator() { return iterator(new PredicateTrue()); } private class CListIteratorWithPredicate implements Iterator { Cell current = first; Cell next = first; Predicate p; CListIteratorWithPredicate(Predicate p) { this.p = p; } public boolean hasNext() { if (next == current) { for (next = current.next(); next != end && !p.predicate(next.data()); next = next.next()) ; } return next != end; } public Object next() { if (! hasNext()) throw new NoSuchElementException(); current = next; return current.data(); } public void remove() { if (!current.isValid()) throw new IllegalStateException(); if (cursor == current) cursor = current.prev(); if (next == current) hasNext(); current.remove(); size--; } } public Iterator iterator(Predicate p) { return new CListIteratorWithPredicate(p); } public String toString() { String s = "cursor = " + cursor + "\n"; for (Cell c = first.next(); c != end; c = c.next()) s += c + "\n"; return s; } }