Lab 10: Using ArrayLists, Traversals, loops and function Objects


Today, you 'll learn how to manipulate objects of the ArrayList class, how to use it to implement the ETraversal interface and how to sort a list without using recursive calls. We will use the generics (type parameters), but will do so by example, rather than through explanation of the specific details.

Throughout the lab we will work on lists of music albums.

Class for Albums

Launch Eclipse, start a Project called Lab10 and import the files from lab10.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.

Task 1:

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


Using ArrayList with Mutation

Open the web site that shows the documentation for Java libraries Java API.

Find the documentation for ArrayList.

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

Other methods of this class are isEmpty(checks whether we haved added any elements to the arraylist), contains(checks if a given element exists in the arraylist), 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:

Design the method that determines whether the album at the given position in the given ArrayList of Albums has the given title.

Design the method that determines whether the album at the given position in the given ArrayList of Albums was recorded before the given year.

Design the method that produces a String representation of the album at the given position in the album list.

Design the method that swaps the elements of the given ArrayList at the two given positions.


Take a look at the AlbumListTraversal class. It allows you to traverse the album list.

Task 3:

Design the method that consumes an AlbumListTraversal and counts the number of albums recorded before the given year.


More Mutation

If you feel you need more practice with mutation, try the follwing tasks. In any case, finish them at home - just for practice:

- Write an equals method in the Album class which returns true if this album is equal to the given album and false otherwise.
- Use it to test the behaviour of an ArrayList. Add elements and test if they are contained, access an element at a specified index and see if it's the one you expected etc. Create at least one test (in the testMutation method) for each new method you learned.


Converting recursive loops into iterative loops

We will look together at the four examples of makeString 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.

// TEMPLATE:  
... tr.hasMore() ...             -- boolean         ::PREDICATE
    if false:                    -- result??        ::BASE CASE
    if true:  ... tr.current()   -- E               ::CURRENT
              ... tr.advance()   -- ETraversal      ::ADVANCE

The type of the empty (base) case corresponds to the return type of the method.

For the makeString method this is the String "-----".

Task 4.

Look at all four variants and identify these parts in each of them. Look also at the tests for these methods in the Examples class.

After you understand the four ways of writing loops, design the loop that produces all elements in the original list that satisfy the given selector. Use all four ways of implementing the loop. Test the methods by producing all albums recorded before the given year.

Additionally, if time permits, design and test andMap method.

  // print all elements in the given traversal
  public String makeString(ETraversal tr){
    if (tr.hasMore())                             // PREDICATE
      return tr.current().toString() + "\n" +     // CURRENT
             makeString(tr.advance());            // ADVANCE
    else
      return "-----";                             // BASE CASE
  }	

  // print all elements in the given traversal using for loop
  public String makeStringWhile(ETraversal tr){
    // preamble: initialize the empty BASE CASE clause
    String result = "------";
    
    // loop header: while(PREDICATE)
    while(tr.hasMore()){ 
      
      // loop body: uses CURRENT element
      result = result + "\n" +
      tr.current().toString();
      
      // loop update: ADVANCE the iterator
      tr = tr.advance();
    }
    
    // postmortem: produce the result
    return result;
  }   

  // print all elements in the given traversal using for loop
  public String makeStringFor(ETraversal tr){
    // preamble: initialize the empty BASE CASE clause
    String result = "------";
    
    // loop header: for(initializer; PREDICATE; ADVANCE)
    for(; tr.hasMore(); tr = tr.advance()){
      
      // loop body: uses CURRENT element
      result = result + "\n" +
      tr.current().toString();
    }
    
    // postmortem: produce the result
    return result;
  }   

  // print all elements in the given traversal using for loop
  public String makeStringForCounted(ArrayList alist){
    // preamble: initialize the empty  BASE CASE clause
    String result = "------";
    
    // loop header: for(initializer; PREDICATE; ADVANCE)
    for(int index = 0; index < alist.size(); index = index + 1){
            
      // loop body: uses CURRENT element
      result = result + "\n" +
      alist.get(index).toString();
    }
    
    // postmortem: produce the result
    return result;
  }   

Challenge

Design the selectionSort method that consumes an ArrayList and a Comparator.

Hints: