CS 27500 - Programming Assignment 5

This assignment makes use of the files contained in this zip file. This assignment is due Friday, December 8.

This assignment is based on the material from Sections 5.5 and 5.6 from the course textbook.

Create a generic class WeirdArrayr<T> that implements the Iterable<T> interface. The WeirdArray<T> class should contain a private reference to an array that will hold references to objects of type T. The WeirdArray<T> class should have a constructor that takes a single integer n and creates an empty array of size n. The WeirdArray<T> class should have a getElement(int i) method that returns a reference to the element of type T stored at index i in the private array, and a setElement(int i, T e) method that puts a reference to a T object at index i in the private array. The WeirdArray<T> class should have a getLength() method that returns the length of the private array. And, since WeirdArray<T> implements the Iterable<T> interface, the WeirdArray<T> class should have a iterator() method that returns a reference to a Iterator<T> object. This method should construct, and then return a reference to, a WeirdIterator<T> object. The WeirdIterator<T> class is described in the next paragraph.

Create a WeirdIterator<T> class that implements the Iterator<T> interface. Here is how your iterator should iterate through the array. If the array has an odd number of items, return the middle item first, then the item just before the middle item, then the item just after the middle, then the item two places before the middle, then the item two places after the middle, then the item three places before the middle, etc. If the array has an even number of items, first return the last item of the first half of the array, then the first item of the second half of the array, then the second to last item of the first half of the array, then the second item of the second half of the array, then the third to last item from the first half, etc. (Notice that in both cases, the iterator starts in the "middle" of the array and then works it way towards the "ends" of the array.)

Your WeirdIterator<T> class should have one constructor that takes a reference to a WeirdArray<T> object (the object that it will iterate through). Since the WeirdIterator<T> class implements the Iterator<T> interface, the WeirdIterator<T> class has three methods, hasNext(), next(), and remove(). The remove() method does not have any meaning in this example, so it should throw a UnsupportedOperationException. The hasNext() and next() methods are what actually implement the iterator as described above. In order to implement the iterator, your WeirdIterator<T> class can have any fields or extra methods that you might think are useful. You will definitely need at least a field to remember which WeirdArray is being iterated and a field to remember the current position (or index) of the iterator as it iterates through the array.

In the definition of your WeirdArray<T> class, there is one small technicality that needs to be worked around (see pages 263 - 265 of the textbook). Java does not allow the construction of arrays whose type is given by a type parameter (like T). In other words, you cannot have a line of code like this.

     T[] theArray = new T[n];

when T is a type parameter. The declaration T[] theArray is not the problem, the problem is with the creation of the array (using new). You get around this limitation by creating an array of type Object

     Object[] theArray = new Object[n];

and then using a cast when a method needs to return an element from within the array. The resulting code will work correctly, but unfortunately the compiler will complain about it by issuing warnings of "unchecked casts". This is one of the few places in your generic code where it is OK to use the @SuppressWarnings("unchecked") annotation.

In the zip file there is a program TestIterator.java that tests your implementations of the WeirdArray<T> and WeirdIterator<T> classes. Do not make any changes to the TestIterator.java file. When TestIterator.java runs, it should produce output like that contained in the file test_output.txt.

When you have WeirdArray<T> and WeirdIterator<T> working, implement a second iterator, WeirdIterator2<T>, for the WeirdArray<T> class. Here is how your second iterator should iterate through the array. The iterator should return the first element of the array first and it should return the last element of the array second, and it should then return the second element, followed by the second to last element, then the third element, followed by the third from last element, etc. The iterator should stop when it gets to the "middle" of the array.

In the zip file there is a program TestIterator_2.java that tests your implementation of the WeirdIterator2<T> class. Do not make any changes to the TestIterator_2.java file. When TestIterator_2.java runs, it should produce output like that contained in the file test_output_2.txt.

The reason for designing two iterators is to help you understand why the Java designers created the Iterable and Iterator interfaces the way they did. At first, it would seem more natural to have the hasNext() and next() methods in the Iterable interface so that an iterable collection would know how to iterate through itself. But then there could be only one way to iterate through a specific collection (like WeirdAray), the way built into the collection.

By having the iterator() method of the Iterable interface return an Iterator object, and then having the hasNext() and next() methods in the Iterator interface, it is possible to separate the way you iterate through a container from the container itself. In fact, you can even design an Iterator for a container that is not Iterable (how?). When a container is Iterable, what that really means is that the container has a preferred way to be iterated (using the Iterator returned by the iterator() method). But if we need to, we can define multiple other ways to iterate through the container by defining multiple Iterator classes that all take the specific container class in their constructors.

Turn in a zip file called CS275Hw5Surname.zip (where Surname is your last name) containing your versions of WeirdArray.java, WeirdIterator.java, and WeirdIterator2.java.

This assignment is due Friday, December 8.