Inserting and Retrieving Items
Overview
In this part of the lab, we will add functionality to our MyLinkedList class to insert and retrieve items from our data structure. We will also continue to practice using unit tests to debug and validate our implementation.
Adding Items to MyLinkedList
The first main operation we will work on programming is adding items to our data structure since we cannot do anything unless it is storing data. Given how linked lists store data, we need to first create a private helper method that will simplify the processing of adding data to our doubly linked list.
Implementing the getNth Method
To be able to both insert and retrieve data at given indices within the linked list, we first need to be able to get the DoublyLinkedNode object that is stored at nearby indices. To help with this process, we will create a private DoublyLinkedNode getNthNode(int index) method that traverses the linked list from its beginning to find the n-th DoublyLinkedNode in the list. More specifically, this method should:
- Start with the beginning of the linked list, available as
this.firstNode. - Also create an integer
countvariable that counts how manyDoublyLinkedNodesthat you have visited so far. - Using a
whileloop (similar to what you used in Part 1 of the Warmup), keep following thenextinstance variable of theDoublyLinkedNodeuntil you either reach then-th node or you reach the end of the list (i.e., when the current node is null). If you reached then-th node, return it. If you reached the end of the list before then-th node, throw anIndexOutOfBoundsExceptionwith a meaningful error message (like in Lab 3 Part 2).
Implementing the add(int index, T item) Method
Our next method public void add(int index, T item) will be responsible for adding a given T item into a desired index in the linked list. This method should:
- First check whether
itemisnull– we do not want to be adding anynullitems to our linked list. If so, throw aNullPointerException. - Next check whether
indexmakes sense given the current number of items in the array list. If theindexis negative or too large, we should throw anIndexOutOfBoundsExceptionwith an appropriate error message - If we currently have an empty list (i.e.,
size == 0), then we need to create a newDoublyLinkedNodethat contains the givenitemand make it both thefirstNodeandlastNodeof the linked list - If
indexis the start of our list (i.e.,index == 0), then we need to add the item to the beginning of the linked list. This will involve creating a newDoublyLinkedNodethat contains the givenitemwith the correctnextnode, updating thepreviousinstance variable of itsnextnode, and saving the new node at the beginning of the list. - Instead, if
indexis the end of our list (i.e.,index == size), then we need to add the item to the end of the linked list. This will involve creating a newDoublyLinkedNodethat contains the givenitemwith the correctpreviousnode, updating thenextinstance variable of itspreviousnode, and saving the new node at the end of the list. - Otherwise, we need to add the item somewhere else that is inside the linked list. Again, we will need to create a new
DoublyLinkedNodethat contains the givenitemwith the correctpreviousandnextinstance variables (yourgetNthNodemethod should be really helpful here), and saving the new node’s order in the list by changing the appropriate instance variables of itspreviousandnextnodes. - Increase the
sizeof the list by 1.
README
This order of operations within each of Steps 3-6 is very important so that all of the nodes in the linked list will be linked in the correct order both forwards and backwards. It will likely be very helpful to draw out what the list will look like after the additions in each of the Steps 3-6 to help guide your implementation – it definitely helps us professors!
Testing add(int index, T item)
Before we continue, we should test some of the behaviors of our add(index, item) method. Unit tests that we want to consider at this point include:
- Making sure that a
NullPointerExceptionis thrown when you try to insert anullitem into the linked list. - Making sure that an
IndexOutOfBoundsExceptionis thrown when you try to insert into a negativeindexor anindexthat is too large. - Making multiple additions to the list so that you test each of Steps 3-6 above and make sure the code doesn’t crash (we will verify each case made a correct addition after we implement the
getmethod below).
Hint
Many of your unit tests from Lab 3 will also be useful for the linked list since both data structures implement the List interface. Please feel free to reuse your unit tests from Lab 3 where ever you think it will be helpful – simply copy them from your MyArrayListTest.java file into MyLinkedListTest.java and change any instances of MyArrayList to MyLinkedList.
Note: we can also update our earlier unit test for the size method from Part 1 of this lab to check whether the size instance variable is properly increased each time we add a new item to our linked list.
Implementing and Testing the add(T item) Method
Our second approach for adding items to the linked list is the method public boolean add(T item) that always adds an item to the end of the list. Because we already did all of the necessary work in the previous method (adding to the end of the list was the special case in Step 5), our second add method can simply call the first add method with the appropriate index.
The only other instruction needed in the second add method is to always return true since we successfully added the item to the linked list.
Don’t forget to create unit tests so that you can be sure that this method is working as intended. Your unit tests from the first add method can help us know what to put here.
Retrieving Items from MyLinkedList
We will only have one method for retrieving items from the linked list: public T get(int index). Recall that we created a stub of this method while testing our code so far at the end of Part 1. We should change this method to:
- First verify that the
indexargument is valid, given the current number of items in the array list. Ifindexis out of range, once again throw anIndexOutOfBoundsExeceptionwith an appropriate error message. - Return the item stored in the
DoublyLinkedNodeat the givenindex. Again, yourgetNthNodemethod you created above might be very helpful here!
Testing
Instead of creating new unit tests for the get method, we can instead retrieve items from our lists in the unit tests created above for the two add methods to make sure that the correct items are stored in the correct index. If there are any errors, hopefully the type of error will help you know which method needs debugging and hints at what might be the problem. Remember that the debugger from lab 3 Part 2 could be very helpful here.
Committing Your Progress
Don’t forget to frequently save your progress periodically to GitHub using the add, commit, and push commands with git.