The top will always refer to the next available spot in the array
Due to zero based indexing, the value of top will also correspond to the number of elements in the stack
All push operations will happen at the top index and require an update to top
All pop operations will happen at the top-1 index and require an update to top
An example ArrayStack containing four elements. Note the value stored in top refers to the next available
spot in the array — where the next pushed element would go. Also notice that the value in top corresponds to
the number of elements currently in the stack.
The state of the ArrayStack after an element was pushed. Note that the value of top was increased by one
such that it refers to the next available spot in the array.
The state of the ArrayStack after an element was popped. Note that the value of top was decreased by one.
The state of the ArrayStack after another element was popped. Note that, again, the value of top was
decreased by one such that it refers to the next available spot in the array.
The ArrayStack class will implement the Stack interface
This ensures that the ArrayStack implementation actually implements the operations required to make it a Stack
The ArrayStackis aStack
Anything expecting a Stack will be happy getting an ArrayStack since it is a stack
Note in the below example where it specifies ArrayStack<T>implementsStack<T>
The fields are
An integer top to keep track of where the top of the stack is
The stack array to hold the elements in the stack
Since the ArrayStack is generic its type is T
6/** 7 * Implementation of a stack with an array as the container. The array container will automatically "grow" to 8 * accommodate adding beyond the initial capacity. 9 *10 * @param <T> Type of elements that are to be in the stack11 */12publicclassArrayStack<T>implementsStack<T>{1314privatestaticfinalintDEFAULT_CAPACITY=100;15privateT[]stack;16privateinttop;
Warning
When starting to implement an interface, the IDE may produce a error saying that the interface is not implemented.
This is because Java is expecting all abstract methods from the interface to be implemented. This error will go away
once all abstract methods are implemented.
Example of the error IntelliJ will produce if not all abstract methods from the Stack interface are
implemented.
Like the ContactList example, there will be two constructors
One making use of the default value
The other to create an array of a specified starting capacity
21/**22 * Create an empty ArrayStack of the default capacity.23 */24publicArrayStack(){25this(DEFAULT_CAPACITY);26}2728/**29 * Create an empty ArrayStack with the specified capacity.30 *31 * @param initialCapacity Starting capacity of the fixed length array32 */33@SuppressWarnings("unchecked")34publicArrayStack(intinitialCapacity){35top=0;36// Generic types cannot be instantiated, so an array of type "Object" is created that is then cast to type T.37// This does generate a compile time warning that is being suppressed with the @ annotation.38stack=(T[])newObject[initialCapacity];39}
When doing this, Java will warn that there is now an unchecked type conversion
Java can’t guarantee that the cast will work right
This can be ignored, however, the warning may be suppressed by adding the following before the constructor
@SuppressWarnings("unchecked")
Creating an instance Stack<Integer>s=newArrayStack<>(5);
A visualization of an ArrayStack created with a starting capacity of 5. The instance s could have been
created with Stack<Integer>s=newArrayStack<>(5);. Although the type Integer is specified in the
declaration, there is nothing within the figure to indicate that the elements within the stack would be of type
Integer.
44@Override45publicbooleanpush(Telement){46if(size()==stack.length){47stack=expandCapacity(stack);48}49stack[top]=element;50top++;51returntrue;52}5354/**55 * Returns a new array with double the size of the stack array container and copy the contents from the old array to56 * the new array.57 */58@SuppressWarnings("unchecked")59privateT[]expandCapacity(T[]oldStack){60T[]newStack=(T[])newObject[oldStack.length*2];61for(inti=0;i<oldStack.length;i++){62newStack[i]=oldStack[i];63}64returnnewStack;65}
Notice the @Override annotation before the push method
This tells the compiler that the method push from the interface is being overridden
It is not required to include this annotation, but it can help eliminate errors
Like the ContactList example, a private expandCapacity method is included
If trying to push to a stack that has a full stack array, expandCapacity is called
The private expandCapacity method will
Make a new and larger array
Copy the contents of the old stack array to the new array
Two ArrayStack objects are considered equal if the contents of the stack arrays are equal
Note
Like the other methods in the class, the @Override annotation on the toString, equals, and hashCode
methods tell the compiler that the method is overriding one in another class. However, unlike push, pop,
peek, size, and isEmpty methods, the overridden methods are not from the Stack interface, but the
Object class. All classes inherit from the Object class which has implementations of the toString,
equals, and hashCode methods.
If everything was done correctly, the following code from PlayingArrayStack should work
1importjava.util.NoSuchElementException; 2 3publicclassPlayingArrayStack{ 4publicstaticvoidmain(String[]args){ 5// Create an ArrayStack 6Stack<Integer>myStack=newArrayStack<>(5); 7 8// Check stack is empty 9System.out.println(myStack.size());10System.out.println(myStack.isEmpty());11System.out.println(myStack);1213// Test push14myStack.push(0);15myStack.push(1);16myStack.push(2);17myStack.push(3);18myStack.push(4);19System.out.println(myStack.size());20System.out.println(myStack.isEmpty());21System.out.println(myStack);2223// Test expand capacity24myStack.push(10);25myStack.push(11);26myStack.push(12);27myStack.push(13);28myStack.push(14);29System.out.println(myStack.size());30System.out.println(myStack.isEmpty());31System.out.println(myStack);3233// Test peek34System.out.println(myStack.peek());35System.out.println(myStack.size());36System.out.println(myStack.isEmpty());37System.out.println(myStack);3839// Test Pop40System.out.println(myStack.pop());41System.out.println(myStack.pop());42System.out.println(myStack.pop());43System.out.println(myStack.pop());44System.out.println(myStack.pop());45System.out.println(myStack.pop());46System.out.println(myStack.pop());47System.out.println(myStack.pop());48System.out.println(myStack.pop());49System.out.println(myStack.pop());50System.out.println(myStack.size());51System.out.println(myStack.isEmpty());52System.out.println(myStack);5354// Test peek and pop throwing exception55try{56myStack.peek();57}catch(NoSuchElementExceptione){58e.printStackTrace();59}60try{61myStack.pop();62}catch(NoSuchElementExceptione){63e.printStackTrace();64}65}66}