©2007 Felleisen, Proulx, et. al.

9  Javadocs, Raising and Catching Exceptions Traversals, Mutating ArrayList


The first part of the lab introduces a several new ideas:

The second part introduces ArrayList class from the Java Collections Framework library, lets you practice designing methods that mutate ArrayList objects. We will continue to use the generics (type parameters), but will do so by example, rather than through explanation of the specific details.

In the third part of the lab you will learn how to how to convert recursive loops to imperative (mutating) loops using either the Java while statement ot the Java for statements to implement the imperative loops.

9.1  Documentation, Traversals, Exceptions, Java Libraries

For this part download the files in Lab9-sp2007-Student1.zip. The folder contains the files Balloon.java, ImageFile.java, ISelect.java, IChange.java, TopThree.java, and Examples.java. In addition, there are several new files: The file Traversal.java defines the Traversal interface, the files AList.java, MTList.java, and ConsList.java that define a generic cons-list that implements the Traversal interface. The file IllegalUseOfTraversal.java illustrates the definition of an Exception class. Finally, the Algorithms.java file shows an implementation of an algorithm that consumes data generated by a Traversal iterator.

Create a new Project Lab9-Part1 and import into it all files from the zip file. Again, import the test harness files and jpt.jar.

Generating Documentation

Defining and Handling Exceptions

ArrayList and Java Libraries

9.2  Using ArrayLists and Traversals

In this part of the lab we will work on lists of music albums.

Class for Albums

Launch Eclipse, start a Project called Lab9-Part2 and import the files from Lab9-sp2007-Student2.zip. Take a look at the Album class. You 'll notice that the fields are private and we provide getter methods for the user who wants to access a field outside the class. This way, the user can retrieve the value of a field without changing it.


Design the class BeforeYear that implements the ISelect interface with a method that determines whether the given album was recorded before some fixed year. Remember to test the method.

Using ArrayList with Mutation

Open the web site that shows the documentation for Java libraries


Find the documentation for ArrayList.

Here are some of the methods defined in the class ArrayList:

// how many items are in the collection
int size();

// add the given object of the type E at the end of this collection
// false if no space is available
boolean add(E obj);

// return the object of the type E at the given index
E get(int index);

// replace the object of the type E at the given index 
// with the given element
// produce the element that was at the given index before this change
E set(int index, E obj);

Other methods of this class are isEmpty (checks whether we have added any elements to the ArrayList), contains (checks if a given element exists in the ArrayList -- using the equals method), set (mutate the element of the list at a specific position), size (returns the number of elements added so far). Notice that, in order to use an ArrayList, we have to add

import java.util.ArrayList;

at the beginning of our class file.

The methods you design here should be added to the Examples class, together with all the necessary tests.

Task 2:

9.3  Converting Recursive Loops into Imperative while Loops

We will look together at the first two examples of orMap in the Examples class.

We first write down the template for the case we already know -- the one where the loop uses the Traversal iterator. As we have done in class, we start by converting the recursive method into a form that uses the accumulator to keep track of the knowledge we already have, and passes that information to the next recursive invocation.

Read carefully the Template Analysis and make sure you understand the meaning of all parts.

   return-type method-name(Traversal tr){
   // invoke the methodAcc: | acc <-- BASE-VALUE |
      method-name-acc(Traversal tr, BASE-VALUE);
    return-type method-name-acc(Traversal tr, return-type acc)
    ... tr.isEmpty() ...                       -- boolean     ::PREDICATE
    if true: 
    ... acc                                    -- return-type ::BASE-VALUE
    if false:
    ...| tr.getFirst() | ...                   -- E           ::CURRENT
    ... update(T, return-type)                 -- return-type ::UPDATE
    i.e.: ...| update(tr.getFirst(), acc) | ...
    ... | tr.getRest() |                       -- Traversal<T> ::ADVANCE
    ... method-name(tr.getRest(), return-type)  -- return-type  
    i.e.: ... method-name-acc(tr.getRest(), update(tr.getFirst(), acc)) 

Based on this analysis, we can now design a template for the entire problem -- with the solution divided into three methods as follows:

    <T> return-type method-name(Traversal<T> tr){
      method-name-acc(Traversal tr,| BASE-VALUE |);
    <T> return-type method-name(Traversal<T> tr, return-type acc){
      if (| tr.isEmpty() |) 
       return acc;
       return method-name-acc(| tr.getRest() |,
                              | update(tr.getFirst(), acc) |);
     <T> return-type update(T t, return-type acc){ ... 

Task 3:

Converting while loops into for loops

If you have the time left, repeat all the parts of Task 3 with the remaining two variants of the orMap -- namely the one that uses the for loop with the Traversal and the one that uses counted for loop.

Last modified: Friday, March 16th, 2007 5:05:50pm