156 CHAPTER 7STACKS AND QUEUES
What we have provided code for in Figure 7.2 is a data structure that generates an
exception if an erroneous stack pop is issued. This will force programs to be written
so as to execute correctly under all circumstances, and a program that issued a pop
should never do so without first testing isEmpty to ensure that the pop won’t crash
the program. The test of isEmpty is a natural test in the layer of software that uses
the stack data structure, and the exception is dealt with in the next layer down
that implements the stack.
As an alternative, the layer that implements the stack could simply return a null
value from an erroneous pop and require the programmer using the stack structure
to check for nonnull data every time the pop is issued. If such a mechanism were
used, the test for a valid pop would come after the method call to pop and would
use a test for null instead of coming before the method call to pop and using a call
to isEmpty. The test would be whether or not valid data had been returned. This
would be advantangeous in one sense, in that the stack data structure was robust
under erroneous use, but it can also be considered a dangerous practice. After all,
why does the isEmpty method exist except to test for the presence of data in the
stack? From a philosophical viewpoint, the call to isEmpty is a natural call regarding
the state of the idealized version of a stack. The test for null, on the other hand,
represents a test that involves the implementation characteristics of the stack.
Regardless of which religious tenets are adhered to, they should be adhered to; in
a given program, one of the two versions should be used consistently and exclusively.
Mistakes often happen when one does a mix and match of such styles, or when one
person uses one version and a second person uses the other and they either don’t
communicate properly with each other or one has to rework the other’s code.
7.1.2 Stacks Using Nodes
A stack implemented using a linked list with nodes needs no further code to be
developed except for the new push and pop methods. The push canbedonesim-
ply as a method with a one-line body that wraps and thus renames the earlier
addAtHead method. The pop requires a slight bit of new code; our remove methods
for the linked list passed in the data payload to be searched for in a node and whose
node was to be removed. In the case of the pop, we are specifying that the node
(or rather, the data payload) first in position in the stack be removed, so there is
no contextual search through the data structure.
For completeness, we must also include the isEmpty method and a peek method
that returns the data at the top of the stack without actually popping the stack.
Done in this way, the linked list is more general than the stack because additions
to and deletions from a linked list can nominally be made anywhere in the list, but
the stack in contrast only permits changes at the top of a stack.
We emphasize yet again, because it is a very important point, that the concept of
the stack should be separated from the implementation of the stack. As a concept,