CSCI 1302 Programming Project 3 Summer 2008 Generic Array-based List Class This program is due by midnight on *** Sunday, July 13 ***. In this assignment you will implement and time the performance of a generic list class RingList based on a private array for data storage. It will perform many of the same functions as ArrayList. Since part of the point of the project is to develop your own implementations, your code must not make use of any other collection class such as ArrayList, LinkedList or Vector. On the other hand, it is expected that a private member of type E [] will be the backing store for the elements of type E. Implement your private backing store as a ring buffer (see Section 3.2 of Lewis and Denenberg, *** and Section 7.6 of Simon Gray ***). In this way your RingList could be efficiently used as a queue. In particular, a nonempty RingList should never resize as a result of an alternating series of remove (from the beginning) and add (at the end) operations, no matter how many. You may implement more methods than required. Test your class and its methods on lists of String and lists of Integer. Time selected methods on a large list of randomly generated Integers. The methods timed should include indexOf( element ) when the given element is not in the list, to see how the average time depends on the list size (e.g., time for sizes 100,000, 200,000, 300,000, 400,000, and 500,000). Also time indexOf( element ) when the given element is in a random position in the list, again seeing how the average time depends on the list size. Repeat these experiments for remove( element ). The required methods, with their signatures, return types and behaviors: public RingList( ) : initializes a newly created RingList object so that it represents an empty sequence with the default capacity. public RingList(int sz) : initializes a newly created RingList object so that it represents an empty sequence with capacity sz. public RingList(RingList otherRingList) : initializes a newly created RingList object so that it represents the same list as otherRingList and has the same capacity. public boolean equals(Object o) : returns true if, and only if, object o is a RingList object representing the same list as this (regardless of capacity). public E getFirst( ) : returns the first element in this list. public E getLast( ) : returns the last element in this list. public E get(int index) : returns the element at location index, where the first element is at location 0, etc. public E set(int index, E newvalue) : replaces the element at location index with newvalue, returning the replaced element. public void add(int index, E element) : inserts the specified element at the specified position in this list. public void addFirst(E element) : inserts the given element at the beginning of this list. public void addLast(E element) : appends the given element to the end of this list. public boolean remove(Object o) : removes the first occurrence of the specified element in this list. Returns true if the object is found and false if not. A null reference should be treated as something to be removed from the list. public E removeFirst( ) : removes and returns the first element from this list. public RingList myConcat(RingList otherRingList) : returns this RingList object if otherRingList is an empty list, and otherwize returns a new RingList which represents the concatenation of this list with the other list following it. public String toString( ) : produces the String "RingList::elements:\n"+s_0+"\n"+...+"\n"+s_k+"\n" where k+1 is the size of the list, s_0 is the string returned by the toString method on the first element, and so on through the list *** except that s_j = "nullelement" if s_{j+1} = null. *** public int indexOf(Object elem) : returns -1 if the specified element does not occur in this list, and otherwize returns the smallest location of the specified element in it. The equals( ) method is used to test for equality if elem is not null. public int lastIndexOf(Object elem) : returns -1 if the specified element does not occur in this list, and otherwize returns the *** largest *** location of the specified element in it. The equals( ) method is used to test for equality if elem is not null. public int size( ) : returns the size (number of elements, or length) of this list. public int capacity( ) : returns the capacity (maximum number of elements which it can contain without needing to be resized). public void trimToSize( ) : trims the capacity of this RingList instance to be the list's current size. public void clear( ) : removes all of the elements from this list. Here are some things to note: *The signatures and return types must be followed exactly, so that the teaching assistant or the instructor can test your RingList methods without editing your code. *Your methods should throw IllegalArgumentException, NullPointerException, or IndexOutOfBoundsException as appropriate. In this regard, note that a null reference is considered a valid element of the list (to be searched for, added, removed, etc.) and so should not generate an exception. Also, equals( ) should simply return false if the input is null. To see how to ensure that true is returned only if the input to equals( ) is a reference to a RingList object, study the Class class in the 1.5.0 API, paying special attention to the class literal and the getName( ) method (or, alternatively, the isInstance( ) method). *The behavior of equals( ref ) when ref == null is one aspect of the contract for equals which you can find under Object in the API. Your implementation should fulfill that contract. However you should ignore the remark about hashCode( ) (the contract for which involves equals( )). *Your RingList class should define constants for the default capacity and the resizing factor. Your timing should be done with the default capacity set to 10 and the resizing factor set to 1.5. *In the descriptions above, "index" or "position" refers to the logical index in the list, which for a list of size sz runs from 0 for the first element on up to (sz-1) for the last element. In general this will not be the same as the index in the array which forms the backing store. *Develop this program following proper methodology, starting with a written plan. Develop the code one method at a time, with readable formatting, meaningful identifier names and illuminating comments. For each method, write the test code for it before writing the code for the method itself. *The submission procedure is described on a separate page which is linked from the "projects" page. Follow it carefully. Your submission should include RingList.java, READ.ME, *** timing_results *** (giving the results of your timing experiments along with a short analysis of them), and class files for testing all of the required methods (along with any extra methods you may have implemented for RingList). *A project which does not compile on atlas using version 1.5.0 Java will score 0. Projects which do compile properly will be scored as follows out of 100 (if on time): 30 pts. for good style (meaningful identifier names which indicate class/object by capitlaization, consistent indentation and formatting, comments which make intention clear); 20 pts. for design modularity (generating the goal and playing one move should be separate methods; include testing and debugging methods); 50 pts. for correct operation. *A project which is submitted late will have its score reduced by 10 points for every 24 hours or part thereof that it is late.