What is a Stack?
A stack is a type of data structure that uses the Last In First Out (LIFO) technique or First In Last Out (FILO) technique. The LIFO technique is used to represent the order in which items are added and taken out of a group or organized group of objects or items (Integers, strings, etc). In this case, a stack is represented just like the name. Think of a stack of pancakes on a plate, a stack of books on the table, a stack of plates. Following the proper order, you would add from one end, or the top, and take out from that same end. Using this principle, one can see that it is the very first book or pancake that was added, that would be the last to be taken out.
Properties of a Stack
It should be an ordered array with items of similar data types.
Usually, In Java, the size of the stack is predetermined, and cannot be modified.
An Overflow is when the Stack is full.
An Underflow is when the Stack is empty.
Methods of a Stack
A typical stack has the following properties:
pop(): This method is used to remove the first item at the top of the stack. This function should remove (pop off) and return the item.
push(value): This method is used to add or push a new value into the stack. It may not have to return anything.
peek(): This method is used to view or sneak a peek at the value that is currently at the top of the stack.
isEmpty(): This is a boolean method that returns true or false, depending on whether the stack is empty.
Another method is, isFull(), this is a boolean method used to determine if the stack is full.
Implementation of the Stack
Let us break the steps for implementing the Stack in Java using an Array data type.
Create an ArrayStack class
This is a simple Java class called "ArrayStack" or anything else you want. It is the parent class that will hold all of the properties and methods of our Stack. The class below holds a document comment detailing what our class does. This class will also contain initialization for the properties of the Stack. In this case, our stack will be an array of integers and it will also have a definite index that will always refer to the current head of the stack. The implementation below is also based on the idea that our stack will only hold positive whole numbers greater than 0.
/**
* This is a class that implements a Stack(LIFO) using an Array.
* It contains the following methods: peek, pop, push, and isEmpty.
* @param
*/
public class ArrayStack {
// initialize an array as stackArray
// initialize a head index
int[] stackArray;
int indexHead;
}
Create the stack instance method
This method will be called "stack". It is a public method used to instantiate or generate a new stack with a definite size and index head. To Implement a stack with an array, let us begin by noting some restrictions of the array data type in Java.
A major constraint is that to remove or add elements to an array in Java, one would have to create a new array every single time, This method is highly inefficient.
There is the constraint of having a predefined size.
And finally, all elements in the array must be of the same data type.
To bypass these constraints, inside our Array Stack class method, create a method called "stack":
Set the originally initialized stack array to a new array of a specified length.
Set the index head property to the highest index based on the length. i.e, if the length of the array is 5, the index head will be 4 (length-1). From the above (number 2), notice that we are starting off our index numbering from the top downwards. That is a countdown from 4, 3, 2, 1, 0. This is to ensure easy addition and removal at the head or top of the stack.
We are going to Implement our pop using negative numbers. In place of actually cutting off the item, anytime we pop off a value, we set the value at that index to -1, to indicate that the position or slot is empty. This will help overcome the first constraint mentioned earlier.
// initialize a stack by setting the array to a fixed length, and
// set indexHead to a value
public void stack(int length){
this.stackArray = new int[length];
this.indexHead = length - 1;
}
Implement an isEmpty method
This method will return a boolean (true or false) that will tell us if the stack is empty or not. This method will be written inside the ArrayStack class, just after the stack method. The stack is considered empty if the value at the Index head is 0 or -1. This is valid because as long as our stack is not empty, the value at the top of the stack has to be a Positive Integer greater than 0.
// stack is empty if the value at indexHead is 0 or -1
public boolean isEmpty(){
return stackArray[this.indexHead] == 0 || stackArray[this.indexHead] == -1;
}
Implement a peek method
This method will return the very first item at the top of the stack, i.e the value at index head or return -1 if the stack is empty.
// to peek: return the value of the element at indexHead in the list, if empty, return -1.
public int peek () {
if(isEmpty()){
return -1;
}
else{
return this.stackArray[this.indexHead];
}
}
Implement a push method
This method takes a new positive integer value and attempts to insert it at the head or top of the stack. It checks if the stack is empty or full, before inserting the value at the top.
public void push(int val) {
if (isEmpty() ) {
stackArray[this.indexHead] = val;
}
// else if index is greater than 0 and less than length of the array,
// set value to the current index head minus 1
// set new index head to current index head minus 1
else if ( this.indexHead > 0 && this.indexHead < stackArray.length) {
stackArray[this.indexHead - 1 ] = val;
this.indexHead = this.indexHead - 1;
}
else{
throw new ArrayIndexOutOfBoundsException("Stack is full");
}
}
Implement a pop method
This method removes (by setting the new value of the index to -1) and returns the value at the top of the stack, or -1 if the stack is empty. It sets the value at that index to -1, to signify it as empty, and moves the head of the stack to the previous index. For example, if the head index was 4, and the value at index 4 was 23, we return 23 and set the value at index 4 to -1, the new head index becomes 3. This is shown in the method below.
public Integer pop () { // get the value to be popped int val = stackArray\[this.indexHead\];
// set popped index value to -1 (this is how we pop) stackArray\[this.indexHead\] = -1;
// if the current head is not the root head, i.e. we are not popping the first item in the array, // set new head to the previous index before the popped index if (this.indexHead != stackArray.length - 1) { this.indexHead = this.indexHead + 1; } return val;
}
```plaintext
### Testing The Stack Implementation
To test the stack implementation, we would need to create another class in the same package folder with our Array Stack class, then initialize a main method where testing will occur.
#### Here is the code for testing
public class Program { public static void main(String[] args){ // create a new stack instance, I have called this "myStack"
ArrayStack myStack = new ArrayStack();
// initialize the stack with a length of 5, our top/head will be index 4 myStack.stack(5);
myStack.push(2); // index 4 myStack.push(15); // index 3 myStack.push(13); // index 2 myStack.push(8); // index 1 myStack.push(16); // index 0
System.out.println("current head is: " + myStack.indexHead); System.out.println("popped: "+ myStack.pop()); System.out.println("popped: "+ myStack.pop()); System.out.println("popped: "+ myStack.pop()); System.out.println("popped: "+ myStack.pop()); System.out.println("popped: "+ myStack.pop());
System.out.println("current head is: " + myStack.indexHead); System.out.println("peeked now: " + myStack.peek());
myStack.push(12); System.out.println("current head is: " + myStack.indexHead); System.out.println("peeked: " + myStack.peek());
myStack.push(11); System.out.println("current head is: " + myStack.indexHead); System.out.println("peeked: " + myStack.peek()); } }
#### Here is the Output on the terminal
![Screen Shot 2021-11-23 at 3.30.32 PM.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1637677852402/WbsTj1bmmX.png)
Notice that The first value to be popped off is **16** and this was the last value to be inserted above, and it was inserted at index 0.
Also, notice where the response says **peeked now: -1**, this indicates that the stack is empty, as all items have just been popped off at the top.
Thus, we have successfully been able to implement a Stack using an array data type in Java.
Thank you for following through from the top, I hope you learned something new.
Here is a list of further learning resources.
1. https://www.tutorialspoint.com/data_structures_algorithms/stack_algorithm.htm
2. https://www.simplilearn.com/tutorials/data-structure-tutorial/stacks-in-data-structures
3. https://www.youtube.com/watch?v=r7P9sy5Rar8