Let a be an ArrayList whose entries are again ArrayLists of certain items. In order to iterate over all these items, e.g. for output, two nested loops are necessary:
The problem is to design one single iterator that iterates over all items in the nested ArrayLists.
Such an iterator is the compound iterator. A compound iterator uses a base iterator (in the example the iterator for ArrayList a0) and a subiterator (in the example the iterator for ArrayList a1), furthermore a function composeItems for forming one new object from the two cursor objects that is returned by the next function of the compound iterator.
The compound iterator follows the bridge design pattern. It uses a behavior that contains the base iterator, the subiterator, and the function composeItems (Figure 1). Furthermore, the behavior contains a factory method for creating the so-specified compound iterator.
Figure 1: Class diagram of a compound iterator with behavior NestedArrayLists
Only class NestedArrayLists, depicted in blue, is to be written by the user (see next section).
The following program examples do not use type parameters. The import statements required for Iterator and ArrayList have been omitted for shortness.
The behavior NestedArrayLists creates a compound iterator that iterates over an ArrayList of ArrayLists. The main ArrayList is passed as a parameter to the constructor. Then, three methods are needed to specify the functionality of the compound iterator.
Any behavior of a compound iterator extends the abstract class CompoundIteratorBehavior that requires methods baseIterator, subIterator and composeItems.
In the method baseIterator the base iterator is specified, and in the method subIterator the corresponding subiterator, depending on the currsor object of the main ArrayList. In this example, the method composeItems uses only the cursor object of the sub-ArrayList. The factory method that returns the compound iterator is provided by the base class CompoundIteratorBehavior.
The following main function in class TestNestedArrayLists tests the compound iterator for NestedArrayLists.
Of course, in this simple example the overhead for using a compound iterator may be too high. However, since the compound iterator implements the iterator interface itself it can be used everywhere where an iterator is appropriate, e.g. as a base iterator in a filter iterator or as a subiterator in another compound iterator.
The program example is based on tested implementations of the classes Compound-Iterator and Compound-IteratorBehavior.
A way to find possible moves m in the domino game is the following:
Method:
for all free neighbour fields q of p
As an example, figure 2 shows some the fields occupied by domino pieces. One of the free neighbour fields of the end of the domino chain p is denoted by q, and one of the free neighbour fields of q is denoted by r. Thus (q, r) is a possible location for the next domino piece.
Figure 2: Possible location (q, r) of next domino piece
Assume we have an iterator FreeNeighbourIterator that iterates over all free neighbour fields of a certain field p. We combine this iterator with another FreeNeighbourIterator to a compound iterator to iterate over all possible locations for the next domino piece. The compound iterator is generated using the behavior FreeNeighbourLocations.
With new FreeNeighbourLocations(board, p).iterator() we get an iterator that iterates over all possible locations of board board that are adjacent to field p (such as (q, r) in figure 2).
Combining this iterator again with an iterator over all matching domino pieces s will result in an iterator for the possible moves.
Next: [up]