In this prelab, you will tackle some of the non-programming issues related to the second full lab assignment. Please write or type up your solutions, and hand in a paper copy before 9am on Monday. Late prelabs are not accepted.
In this week's lab, you will construct your very own implementation of the ArrayList data structure, which we will oh-so-inventively name MyArrayList. You will likely be using this data structure frequently. It has a fairly simple interface and behaves similarly to the Python list structure.
list.add(x)- adds x to the end of the list (like Python's
list.add(i,x)- adds x at index i in the list moving items down by 1 (like Python's
list.set(i)- gets or replaces item at index i in the list (like Python's
list.remove(i)- removes the item at index i in the list moving items down by 1 (like Python's
list.size()- returns the number of items in the list (like Python's
MyArrayList implements the Java
interface. That is, you have to provide implementation for all of the (abstract) methods contained therein. There are more than 20 such methods, however, and that could take you awhile to get through. Moreover, some of the methods are "redundant" in the sense that they can be implemented using the other methods (for example, you can implement
isEmpty() by returning
(size()==0)). Fortunately, the folks at Java have provided a lovely abstract class
AbstractList that provides some very basic and default behavior for a List. Some of the methods still aren't implemented (that is, they are abstract) and some of them may have inefficient implementation (that is, you'll want to override them), but it's useful nonetheless. Thus your MyArrayList class should extend AbstractList in order to reap the benefits; because AbstractList implements the List interface, you will implicitly be required to do so as well (but do not have to declare your intention to implement explicitly).
As you might expect from the name, the underlying storage for an ArrayList is an array. That is, an ArrayList is really just an array with the extra functionality of dynamic resizing. Thus, the number of spaces in the array (its capacity) might be different than the number of items currently in the MyArrayList (its size). The capacity must always be greater than or equal to the size -- otherwise we're not storing everything. (Note: you don't need to make things smaller after removing items.)
Hopefully by now it is clear that when you add something to MyArrayList, you might need to resize things. Otherwise, you risk not being able to fit all of your lovely data into your structure. Let's consider how much larger we should make the array each time we resize.
You will write a private resize() method that increases the length of the data array as part of your assignment. You will need to make a new array of larger size, copy the data from the old array into the new array, and change the reference to point to your new array. Let's assume that our storage array is declared AnyType data.
Expanding the array by 1 each time an item is added:
Suppose you start with an ArrayList of size 0 and capacity 1,
data.length==1), and you add
n elements one-by-one to the ArrayList. After the first item is added,
you'll have to call resize for each additional add. When you resize, you'll
copy all the previous values over to the new array.
Consider the following questions.
I will accept any answer in an acceptable range, but be as accurate as you can. Completing the following chart may help organize your thoughts (I've filled in a few boxes for you).
Your final answer would be the sum of the entries in the bottom row. It may be useful to remember that 1+2+4+...+n = n(n+1)/2
|Number of items (size)||1||2||3||4||5||6||7||8||9||10||11||12||13||14||15||16||17||18||...||n-1||n|
|calls resize? (Y/N)||N||Y||Y||Y||...||Y||Y|
|# assignment statements in resize( )||0||1||2||3|
*** Total number of assignments performed (in terms of n):
Now suppose you change your resize method to double the length of the data array, instead of only incrementing by one. Answer the previous question again and comment on the result. If it helps, you may assume that n is a power of 2. It may be useful to remember that 1+2+...+2p= 2p+1-1 = 2*2p-1.
Again, you are summing the values in that bottom row. I'm most interested in the total number of assignments and the chart is to help you determine this value.
|Number of items (size)||1||2||3||4||5||6||7||8||9||10||11||12||13||14||15||16||17||18||...||n-1||n=2p||n+1|
|calls resize? (Y/N)||N||Y||Y||N||Y||...||N||Y|
|# assignment statements in resize( )||0||1||2||0||4||0||n|
*** Total number of assignments performed (in terms of n, so get rid of all p's):
An important part of developing a reusable ADT is being able to determine if you've correctly implemented everything. A portion of this lab will be writing some test programs to test your MyArrayList implementation, to see if you can spot any problems with it.
A good programming technique is to "write a little, test a little." By being able to come up with short tests that you can use right after you create a method, you will have greater confidence and insight as to the location of any bug that appears later.
If you adhered to the honor code in this assignment, add the following statement at the top of your prelab.
I have adhered to the Honor Code in this assignment.
Write or type your solutions and hand in a paper copy by the deadline listed at the top of this prelab. Late prelabs will not be accepted.