Due 9am, Monday, October 02 2017
In this prelab, you will familiarize yourself with some of the design and implementation issues in the upcoming lab 4. Please write or type up your solutions, and hand in a paper copy before class on Monday. Remember, late prelabs receive zero credit.
In this section of the lab you will implement your own doubly-linked list and a corresponding iterator.
Suppose your MyLinkedList<T> class is implemented as a doubly linked list and contains Node as a nested class:
public class MyLinkedList<T> extends AbstractList<T> { class Node { T data; Node prev, next; // more code here } // Class variables for MyLinkedList private Node head; private Node tail; private int size; /* Lots more code will go here */ }
where both head and tail point to sentinel nodes pointing at each other and the size is 0 when the list is empty.
public MyLinkedList() { // Your answer will go here }
private Node getNth(int index) { // Your answer will go here }that returns a reference to the Node at position index in the linked list. Write the method body for this method. For the prelab, you may assume that index is within the range 0 to size-1 (but check this in the actual lab!).
Your MyLinkedList class will generate a ListIterator when the factory method listIterator() (from AbstractList) is invoked.
An Iterator provides an easy way for someone to go through every item in your collection.
The Iterator<T>
interface has three methods:
// returns true if there are more items to see public boolean hasNext(); // returns the next item in the list (and advances forward) public T next(); // removes the last item returned by next() public T remove();
A ListIterator supports going both backwards and forwards, so it also contains a couple of other methods
// returns true if there are more items to see going backwards public boolean hasPrevious(); // returns the previous item in the list (and advances backwards) public T previous();
After one call to next()
, the iterator is logically in the state shown below (click to enlarge).
If you call next()
you would get B,
but if you called previous()
instead you would get A.
You don't want to always have to re-start at the head each time a user calls next()
, so your ListIterator will need to keep track
of its position in the list based on a Node instead of an index (which you might choose to use when constructing an ArrayList iterator).
Fill in the following methods listed in this anonymous class:
(For the prelab you may ignore throwing exceptions for going too far.)
public ListIterator<T> listIterator() { return new ListIterator<T>() { // What class members do you want here? public boolean hasNext() { // what line of code goes here? } public T next() { // what lines of code go here? } public boolean hasPrevious() { // what line of code goes here? } public T previous() { // what lines of code go here? } // ... and some more in the next question ... }; }
next()
).
We also want an add(x) method that adds a new item just before whatever would have been returned by next() but just after whatever would have been returned by previous()? (This would put x in between A and B in the above diagram.)
Give brief method bodies for these as well:
public void remove() { // what lines of code go here? } public void add(T x) { // what lines of code go here? }