Introduction
- There are many ways to store and operate over data. For different situations, we use different data structures that are perfect or near-perfect for the intended operation.
- One such operation that is very common in software development is the Last In First Out operation or L.I.F.O as it is popularly known.
The data structure itself is called a Stack and the operation that it supports is L.I.F.O.
Use Case
- L.I.F.O behavior can be seen in real life as well as in computer programming. A stack of plates is a very good example where the last dish will be placed at the top and taken out from the top as well.
- In computer programming, recursion is a good example of stack data structure. As we call functions recursively they are being stacked and executed in reverse order.
- Other would-be undo operations in software. Consider games such as Chess or Sudoku which allow us to undo up-to certain moves or paint that allows us to go back, they both behave as L.I.F.O order.
Let’s see how can we achieve L.I.F.O behavior in Java.
Implementation In Java
- In this article, we will discuss two Stack implementations in java.
- The first one is Stack Class which implements Vector class in Java
- Another is the Deque interface that provides various implementations such as ArrayDeque that can be used as Stack in Java.
Stack Class Implementation
- Stack class extends the vector class which itself implements the list interface.
- Stack class provides push(), pop(), isEmpty() and peek() operation which is typically required operations for L.I.F.O
// stack of last 5 moves
Stack<Integer> stack = new Stack<>();
// push the moves into the stack
stack.push(1);
stack.push(3);
stack.push(2);
stack.push(0);
stack.push(5);
// goto the previous move
int count =0;
while(!stack.empty()) {
Integer i = stack.pop();
if(i==target) {
count++;
break;
}
}
// get the top of the stack
System.out.println("top "+stack.peek());
ArrayDeque Class Implementation
- ArrayDeque implements the Deque data structure which is a double-ended queue.
- Since it’s Deque we can add and remove elements from both ends, hence we can use a subset of the function of deque to achieve L.I.F.O.
- Below are the push(), pop(), isEmpty() and peek() operation which we can use to achieve L.I.F.O.
// push operation
Deque<Integer> stack = new ArrayDeque<>();
stack.push(1);
stack.push(3);
stack.push(2);
stack.push(0);
stack.push(5);
// goto the previous move
int count =0;
while(!stack.isEmpty()) {
Integer i = stack.pop();
if(i==target) {
count++;
break;
}
}
// get the top of the stack
System.out.println("top "+stack.peek());
Difference Between Stack and Deque
- As we just saw Stack and Deque both can be used to achieve L.I.F.O-like behavior, but there is some difference in both the implementations.
- Stack is a class that extends the vector class. Hence stack is not extendable if our current class is already extending some other class (Since java doesn’t support multiple inheritances)
public class Stack<E> extends Vector<E>
- But Deque is an interface, hence we can implement it in our class.
public interface Deque<E> extends Queue<E>
- Stack is thread-safe while Deque is not thread-safe, hence should be avoided if that is necessary.
- There are some other differences as well like to iteration and supported methods beyond L.I.F.O, but I will skip that for future articles.
Conclusion
- Stack is a data structure that is being used in computer programming very often to build scalable software and we can see its reference from real-life use cases like stacks of dishes and books.
- Java provides a Stack class and Deque interface which can be used to achieve Stack behavior that is L.I.F.O.
- Although both approaches has differences hence we should know about them before using them in our software design.
Bonus Tip
- If you want to upskill your Java, you should definitely check out this bestseller course