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
noinnerclasses
shows 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 usedcurrent
to 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 ofStringStackArrayIterator
s 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 aStringStackArray
in the constructor somewhat breaks encapsulation: it means that the independent classStringStackArrayIterator
is dependent upon the representation used inStringStackArray
. -
Package
innerclasses
shows how the iterator classes can be realised as inner classes ofStringStackArray
andStringStackList
. 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
anonymousinnerclasses
uses 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!