Solution to 85bb: String stack iterators
See code at solutions/code/tutorialquestions/question85bb
The tricky part of this question is Step 3 -- implementing the iterator classes. I have provided three solutions:
-
Package
noinnerclassesshows how this can be realised without using inner classes. Look at StringStackArrayIterator.java. You'll see that instances of this class are constructed by passing in the internals of aStringStackArray. Look at the way I have usedcurrentto point to the next element of the stack that should be returned by the iterator. As noted in the question, the disadvantages of this approach are that it allows the creation ofStringStackArrayIterators that do not correspond to any string stack (e.g., one can simply write:new StringStackArrayIterator(new String[10], 4)), and that passing the internals of aStringStackArrayin the constructor somewhat breaks encapsulation: it means that the independent classStringStackArrayIteratoris dependent upon the representation used inStringStackArray. -
Package
innerclassesshows how the iterator classes can be realised as inner classes ofStringStackArrayandStringStackList. In StringStackArray.java, notice that we declare:
private class StringStackArrayIterator implements StringStackIterator ...
This class is private, meaning that it is only visible inside StringStackArray. In the constructor, notice that we can write:
private StringStackArrayIterator() {
current = stackPointer - 1;
}
That is, we can refer to the stackPointer field of StringStackArray. This is because every StringStackArrayIterator instance will have an
associated StringStackArray.
This solution solves the visibility and encapsulation problems associated with having a separate class for each iterator.
- Package
anonymousinnerclassesuses anonymous inner classes to represent the iterator classes. This corresponds to the Advanced part of the question. Compare the inner classes version with the anonymous inner classes version to get a feeling for how this works. Using an anonymous inner class means that instances of the class can only be instantiated at the specific point where the anonymous class is declared. This can be advantageous if a single point of instantiation is what you want.
Whichever solution you look at, look into the AbstractStringStack class to see that we can implement toString()
completely abstractly by using the iterator facilities that a StringStack is now guaranteed to provide!