Java Reference
In-Depth Information
structure. The link member in the bottom node is set to null to indicate the bottom of
the stack. A stack is not required to be implemented as a linked list—it can also be imple-
mented using an array.
The primary methods for manipulating a stack are push and pop , which add a new
node to the top of the stack and remove a node from the top of the stack, respectively.
Method pop also returns the data from the popped node.
Stacks have many interesting applications. For example, when a program calls a
method, the called method must know how to return to its caller, so the return address of
the calling method is pushed onto the program-execution stack (discussed in Section 6.6).
If a series of method calls occurs, the successive return addresses are pushed onto the stack
in last-in, first-out order so that each method can return to its caller. Stacks support recur-
sive method calls in the same manner as they do conventional nonrecursive method calls.
The program-execution stack also contains the memory for local variables on each
invocation of a method during a program's execution. When the method returns to its
caller, the memory for that method's local variables is popped off the stack, and those vari-
ables are no longer known to the program. If the local variable is a reference and the object
to which it referred has no other variables referring to it, the object can be garbage col-
lected.
Compilers use stacks to evaluate arithmetic expressions and generate machine-lan-
guage code to process them. The exercises in this chapter explore several applications of
stacks, including using them to develop a complete working compiler. Also, package
java.util contains class Stack (see Chapter 16) for implementing and manipulating
stacks that can grow and shrink during program execution.
In this section, we take advantage of the close relationship between lists and stacks to
implement a stack class by reusing the List<T> class of Fig. 21.3. We demonstrate two dif-
ferent forms of reusability. First, we implement the stack class by extending class List .
Then we implement an identically performing stack class through composition by
including a reference to a List object as a private instance variable. The list, stack and
queue data structures in this chapter are implemented to store references to objects of any
type to encourage further reusability.
Stack Class That Inherits from List<T>
Figures 21.10 and 21.11 create and manipulate a stack class that extends the List<T> class
of Fig. 21.3. We want the stack to have methods push , pop , isEmpty and print . Essential-
ly, these are the List<T> methods insertAtFront , removeFromFront , isEmpty and print .
Of course, class List<T> contains other methods (such as insertAtBack and removeFrom-
Back ) that we would rather not make accessible through the public interface to the stack
class. It's important to remember that all methods in List<T> 's public interface class also
are public methods of the subclass StackInheritance<T> (Fig. 21.10). Each method of
StackInheritance<T> calls the appropriate List<T> method—for example, method push
calls insertAtFront and method pop calls removeFromFront . StackInheritance<T> cli-
ents can call methods isEmpty and print because they're inherited from List<T> . Class
StackInheritance<T> is declared in package com.deitel.datastructures (line 3) for re-
use. StackInheritance<T> does not import List<T> —the classes are in the same package.
Class StackInheritanceTest 's method main (Fig. 21.11) creates an object of class
StackInheritance<T> called stack (line 10). The program pushes integers onto the stack
(lines 13, 15, 17 and 19). Autoboxing is used here to insert Integer objects into the data
 
Search WWH ::




Custom Search