Lab 8b
Goals: The goals of this lab is to learn how to work with parametric data types.
In the second part of this lab we will learn how to work with mutable direct access data types defined in the Java Collections Framework library.
Parametric Data Types
In the previous exercise we have defined two lists of items, but the only difference between them was the type of data the list contained.
In this part of the lab we will abstract over the data type the lists contain.
Start with a new project Lab8b and import into it the files saved in Lab8b-Lists.zip.
You should have the following files, where the ILo file contains a parametrized definition of a list of items of the type given by the parameter T:
Book.java
Song.java
ISelect.java
ILo.java
ExamplesLists.java
NoSuchElementException.java
Run the program and read the code.
Make an example of a list of books that contains four books. Make an example of a list of songs that contains four songs.
Design the method for the classes that represent a list of data items that counts the number of items in the list.
Every class in Java extends the class Object that among other things defines the method with the signature String toString() that produces a String representation of the object. The default implementation is basically useless. Override this method in the classes Book and Song by designing a method that produces a String that shows the book or song title, and the values of the other fields as well.
Design the method stringList in the classes that represent a list of items that produces a list of String representations of the objects in the list.
Add to the file that defines the ISelect interface the definition of a class BookByPrice that represent a predicate that selects all books that have the price in the given range (low <= price <= high), and another one SongsBy that selects all books by the given artist. Make sure you have tests and examples.
Design the method filter for the classes that represent a list of items that consumes a predicate (an instance of the class that implements ISelect interface and produces a list of all items in this list that satisfy the given predicate.
Design the method find for the classes that represent a list of items that consumes a predicate (an instance of the class that implements ISelect interface and produces the first item in the list that satisfies the given predicate. If no such item is found, the method throws the NoSuchElementException.
The class NoSuchElementException shows the standard definition of a new RuntimeException class.
The Java Collections Framework
Start this part of the lab by looking at the web pages for the Java Libraries APIs. Scroll through the All Classes in the lower left frame to find the Comparable and Comparator interfaces. You can see from the descriptions that there is a lot of detail, much more than we would expect from such a simple function-object. We will address some of these issues in the lectures.
Scroll through the All Classes frame on the left again and find the ArrayList class. In lecture we have discussed a number of methods we can use to modify/manipulate and instance of ArrayList. Use the online documentation as you work on this part of the lab.
Understanding the ArrayList data structure
For this part of the lab download the file ExamplesArrayList.java, and add it to your project. It contains one classthe ExamplesArrayList class that has some code designed to show how to work with ArrayList data structure.
Your goal in this part of the lab is to extend the provided test suite for the methods defined for the Arraylist.
Run the tests without changing them and read the code to see what they do. As you can see, we test the methods size, add, get, and set for the class ArrayList.
Read the documentation for the method add. Add new tests that verify the correctness of both variants of the method add.
Read the documentation for the methods isEmpty and clear. Add the tests that verify the correctness of these method.
Read the documentation for the method remove. Add the tests that verify the correctness of both variants of the method remove. Notice, that the variant that removes the desired object uses the identity version of equality for finding the desired object.
Read the documentation for the methods get and set. Add a few more tests for each method to make sure you understand how these methods work.
Mutating ArrayList
Continue with the current project and the test suite in the class ExamplesArrayList.
Define a new instances of ArrayList as follows:
ArrayList arblistSame = this.arblist;
ArrayList arclistSame = this.arclist;
right after the objects arblist and arslist have been declared.
Think of what this means, then augment all tests so you would also test what is happening to the arblistSame object and the arslistSame object.
Now add the following field definition right after the previous ones:
ArrayList arblistOther;
ArrayList arslistOther;
then as the last line of the method initBookList add the following line:
this.arblistOther = new ArrayList(this.arblist);
and as the last line of the method initSongList add the following line:
this.arslistOther = new ArrayList(this.arslist);
Think of what this means, then augment all tests so you would also test what is happening to the arblistOtherand the arslistOther. Draw a picture that shows the difference between the three lists.
Finally, design the method
/**
* EFFECT:
* Swap the values of the items at the two given indices
* in the given <code>ArrayList</code>
*
* ~param alist the given <code>ArrayList</code>
* ~param index1 the location of the first element to swap
* ~param index1 the location of the second element to swap
*/
<T> void swapAtIndices(ArrayList<T> alist, int index1, int index2) { ... }
Notice that this method works for any ArrayList —
it is parametrized over the type of data that its argument alist contains. Test the effect of this method on all three variants of the list of books and all three variants of the list of songs.