import java.util.Iterator; /* List_WC_ViaLink2.java (List with Cursors via Link2) ** ** Java class that implements the ListWithCursors interface, ** in which the list has a Link2-based representation. ** ** @author R. McCloskey ** @version October 2025 ** */ public class List_WC_ViaLink2 implements ListWithCursors { // instance variables // ------------------ private Link2 front; private final Link2 rear; private int length; // constructor // ----------- /* Initalizes this to be an empty list. */ public List_WC_ViaLink2() { rear = new Link2(null); front = rear; length = 0; } // observers // --------- public boolean isEmpty() { return front == rear; } public int lengthOf() { return length; } // Cursor generation // ----------------- public ListCursor getCursor() { return new Cursor(this); } // Iterator generation // ------------------- /* Returns an iterator over this list. */ public Iterator iterator() { return new MyIterator(this); } // Nested Cursor class // ------------------- private class Cursor implements ListCursor { // instance variables // ------------------ private List_WC_ViaLink2 myList; // this cursor's list private Link2 position; // position of this cursor public Cursor(List_WC_ViaLink2 list) { myList = list; position = list.front; } public void dispose() { } // observers // --------- public boolean atFront() { return position == myList.front; } public boolean atRear() { return position == myList.rear; } public T getItem() { return position.item; } public boolean equals(ListCursor cur) { Cursor c; try { c = (Cursor)cur; } catch (Exception e) { return false; } return this.myList == c.myList && this.position == c.position; } public ListWithCursors getList() { return myList; } // navigation mutators // ------------------- public ListCursor toFront() { position = myList.front; return this; } public ListCursor toRear() { position = myList.rear; return this; } public ListCursor toPrev() { if (atFront()) { throw new ListCursorException("A list's front has no predecessor"); } else { position = position.prev; } return this; } public ListCursor toNext() { if (atRear()) { throw new ListCursorException("A list's rear has no successor"); } else { position = position.next; } return this; } public ListCursor setTo(ListCursor cur) { Cursor c; try { c = (Cursor) cur; } catch (Exception e) { String message = "setTo() requires argument be same kind of cursor"; throw new IllegalArgumentException(message); } if (myList != c.myList) { String message = "setTo() requires argument be cursor in same list"; throw new IllegalArgumentException(message); } this.position = c.position; return this; } // list mutation // ------------- public void insert(T newItem) { Link2 newNode = new Link2(newItem, this.position.prev, this.position); if (myList.front == position) { myList.front = newNode; } else { this.position.prev.next = newNode; } this.position.prev = newNode; myList.length++; } public T remove() throws ListCursorException { T result; if (atRear()) { throw new ListCursorException("remove() requires !atRear()"); } result = getItem(); position.next.prev = position.prev; if (myList.front == position) { myList.front = position.next; } else { position.prev.next = position.next; } position = position.next; myList.length--; return result; } public T replace(T newItem) { T result; if (atRear()) { throw new ListCursorException("replace() requires !atRear()"); } result = position.item; position.item = newItem; return result; } public void swapItems(ListCursor cur) { T temp = getItem(); replace(cur.getItem()); cur.replace(temp); } // clone public ListCursor clone() { Cursor result = new Cursor(myList); result.position = this.position; return result; } } // end of private class Cursor private class MyIterator implements Iterator { private ListCursor iterCursor; public MyIterator(List_WC_ViaLink2 list) { iterCursor = list.getCursor(); } public boolean hasNext() { return !iterCursor.atRear(); } public T next() { T result = iterCursor.getItem(); iterCursor.toNext(); return result; } } }