In this lab you will implement a doubly linked list and an iterator for it.
The purpose of this lab is to:
Your first task is to implement a doubly linked list called MyLinkedList<T> and a corresponding ListIterator for your class.
I have some starter code for you here: Lab4.zip Unzip this file into your csci151 lab folder and change the name of the project folder to Lab4<your last name> before you create your Lab4 project in Eclipse. This has a start of the code for your MyLinkedList class, a test program for Part 3, and some data files.
In this lab you create a class called MyLinkedList<T>. Your class should extend AbstractList<T>.
When you have finished your implementation, be sure to test it thoroughly before continuing. In doubly linked lists, the addition or removal of items can be especially tricky as you need to be sure to properly update all of the pointers of the next and previous elements, as well as handle the special cases for removal from the front or tail. Keep a piece of paper with you and draw pictures to help with your coding. Nobody writes this code without referring to pictures.
public class MyLinkedList<T> extends AbstractList<T> { class Node { T data; Node next; Node prev; // more code here for class Node } }
You should only need a single no-argument constructor that creates an empty list and initializes all the necessary variables. We will use sentinal nodes at each end of the list to reduce the number of special cases we have to deal with
You should be able to re-use the tests you wrote in Lab 2 for MyArrayList. Copy the MyArrayListTest.java file into your lab4 folder and rename it to be MyLinkedListTest.java. You will need to delete and re-create your Lab4 project to make the file appear in Eclipse. Or just have Eclipse create the JUnit source file MyLinkedListTest.java and copy and paste from your MyArrayListTest.java file. Then you can open up the file, rename the public class to be "MyLinkedListTest", and then update the methods to use MyLinkedLists instead of MyArrayLists.
Once your MyLinkedList class is working, you will need to create a ListIterator which is returned by the factory listIterator() method. Use a helper class MyLinkedListIterator nested in the same file as MyLinkedList in the same way the Node class is nested within MyLinkedList.
class MyLinkedListIterator implements ListIterator<T> { // class variables here public boolean hasNext() { // your code here } // more methods, etc. }
The text talks about nested classes on p. 161. If you want more, here is Oracle's discussion of nested classes. You can read about anonymous classes here. Most people new to Java, and even some experienced ones, find nested classes easier to handle than anonymous classes. You are free to use either technique,thogh the supplied starter code builds a nested class.
The ListIterator is able to traverse the list by moving across one element at a time
in either direction. It might be helpful to consider that the iterator has
size+1 positions in the list: just before the first element, between that element and the next, ..., and just after the final element.When first constructed, the iterator is logically in the state shown below.
You will need to implement all of the methods of a listIterator -- hasNext()/next(), hasPrevious()/previous(), nextIndex()/previousIndex(), remove(), set(x), and add(x) as discussed below:
There are many ways to keep track of where the iterator currently is. Some people keep pointers to the next node and the previous node. I find it easier to keep a variable left that points to the node just to the left of the current position, and to calculate next() and previous() from that. Since set() and remove() both change based on what direction we were last traversing, I keep boolean flags to tell me if we were moving in the next-direction or the previous-direction.
It is possible, and sometimes useful, to have several iterators working on the same list. If they both try to change the structure of the list you could get into an unpredictable state. Therefore you should check that the list hasn't been modified by someone else before you let an iterator make a modification. An easy way to do this is to have both the list and the iterator keep track of the number of modifications that have been made to the list. When the iterator is created it grabs the list's modification count. Each change the iterator makes to the list increases both its and the lists modification count. However, if you have two iterators modifying the list, one of them will find that its modification count will be different from the list's, so you will know that the list structure has been changed and that iterator is no longer viable. See the text for additional details and suggestions.
We access iterators through the following factory methods in MyLinkedList. Each of these should just create a new MyLinkedListIterator and return it.
Note: You inherit a working ListIterator from AbstractList, but the one you create will be more efficient. For this lab we will depart from the usual Java terminology and call the factory methods myIterator( ) and myListIterator( ) rather than iterator( ) and listIterator( ). We will run grading scripts using the "my" names. Be sure to have methods myIterator( ) and myListIterator( ).
Students often miss the point of iterators. Especially in a structure like a linked list, where you can always access the data through indexing with the get( ) method, iterators seem superfulous. This part of the lab might convince you that they are actually quite useful.
The starter code for this lab includes an application program IterationTester.java. This program opens up the text file whose name is given in args[0] and makes a list of all of the different words that appear in the file. Each time it reads a word it checks whether its wordlist contains this word; if not, it adds it to the list. The program performs this algorithm three times, and prints the number of milliseconds each attempt takes:
Use program IterationTester to complete the following table. Put a README.txt file in your project folder that contains the three times for each of these files. To save you a little time, I have included a start on this README file in the starter code:
File | Words | Unique Words |
ArrayList Time | Iterator Tiome | Indexing Time |
Prufrock.txt | 1084 | 501 | 44 ms | 35 ms | 81 ms |
IHaveADream.txt | 1589 | 630 | |||
EveOfStAgnes.txt | 2902 | 1587 | |||
Hamlet.txt | 32,006 | 7718 | |||
PrideAndPrejudice.txt | 121,557 | 13,065 |
Note that you might need to let the program run overnight to complete the last file. Even Hamlet, which has half of the number of unique words, takes about 25 minutes in my implemeentation of MyLinkedList. I thought about giving you WarAndPeace..... You should see that the linked list with iterators runs in time that is similar to that of the ArrayList with indexing, while the linked list with indexing is far, far worse.
By the way, here are those files:
The files are in a folder textFiles in the project folder. Your arguments forthe Run Configurations file should be similar to "textFiles/Prufrock.txt".
You should hand in a zipped copy of the project folder for this lab. Before you zip the project folder please remove the textFiles folder from it. The project folder should contain a lab4 package with files MyLinkedList.java and IterationTester.java. The projectd folder should also contain a README file with your times from Part 3. . If you adhered to the honor code in this assignment, add the following statement to your README file
I have adhered to the Honor Code in this assignment.
If you have worked with a partner you should both sign the README file, and both of your names should be in a comment on your MyLinkedList.java. Only one of you should hand in the lab; you will both receive the same score for the lab.
You want to keep the graders happy. If there are portions of this code that you know are not working correctly, it would be helful if you included information about what does and what doesn't work in your README file.
In case you don't remember how to make a compressed file, go to your csci151 folder and make a compressed version of your project folder. On a Mac select this folder and select Compress from the File menu. On Windows right-click on the project folder and select Send to -> Compressed (zipped) folder. In either case you should get a zip file. Open the Blackboard course for our class. Click on the Course Material link, then on the Lab 4 link. In the Assignment Submission section click on the Browse My Computer button. this will bring up the usual navigation controls that should allow you to select your zipped project file for this assignment.