java.util.Stack data structure in Java

This article covers basic information on java.util.Stack data structure, common operations performed on the stack, an algorithm along with a code snippet of the most common application of Stack data structure. It also discusses the performance and time complexity of the algorithm and few other applications of Stack.

Prerequisites :

Basic knowledge of Java and data structures.

Definition :

Stack is a linear data structure where operations are performed in a particular order i.e. LIFO (Last In First Out) or FILO (First In Last Out). Which means the last element that is inserted is the first element that is removed.

Stack data structure
Common operations performed on stack data structure:
  1. Push: Adds a new element to the stack. If the stack is full then it is said to be a stack overflow condition.
  2. Pop: Removes an element from the stack. If the stack is empty then it is said to be a stack underflow condition.
  3. Peek: View the top element of the stack.
  4. isEmpty: Checks if the stack is empty.
  5. isFull: Checks if the stack is full.

To learn more about the internal implementation about stack data structure visit https://hetalrachh.home.blog/2020/01/04/java-util-stack-common-operations/

Common application of stack :

Check a well formed expression. Number of opening brackets of each type should be equal to the number of closing brackets of the respective type and the order of the brackets should be correct.

Examples :

(ABC){DEF} [XYZ(LMN)] – well formed expression as the number of opening and closing brackets are equal and the order in which the brackets open and close is well balanced.

(ABC{DEF} [XYZ(LMN)] – not well formed as the number of opening ‘(‘ brackets is not equal to the number of closing ‘)’ brackets, hence not balanced.

(ABC){DEF} [XYZ(LMN)]} – not well formed as the number of opening ‘{‘ brackets is not equal to the number of closing ‘}’ brackets, hence not balanced.

Algorithm :
  1. Declare a map matchingParenMap and initialize it with closing and opening bracket of each type as the key-value pair respectively.
  2. Declare a set openingParenSet and initialize it with the values of matchingParenMap.
  3. Declare a stack parenStack which will store the opening brackets ‘{‘, ‘(‘, and ‘[‘.
  4. Now traverse the string expression input.
    • If the current character is an opening bracket ( ‘{‘, ‘(‘, ‘[‘ ) then push it to the parenStack.
    • If the current character is a closing bracket ( ‘}’, ‘)’, ‘]’ ) then pop from parenStack and if the popped character is equal to the matching starting bracket in matchingParenMap then continue looping else return false.
  5. After complete traversal if no opening brackets are left in parenStack it means it is a well balanced expression.
Code snippet :

Below is the code snippet for checking matching parenthesis using java.util.Stack class which provides the features of a stack data structure.

//map for storing matching parenthesis pairs
private static final Map<Character, Character> matchingParenMap = new HashMap<>();

//set for storing opening parenthesis
private static final Set<Character> openingParenSet = new HashSet<>();

static {
     matchingParenMap.put(')','(');
     matchingParenMap.put(']','['); 
     matchingParenMap.put('}','{'); 
     openingParenSet.addAll(matchingParenMap.values());  
}

//check if parenthesis match
public static boolean hasMatchingParen(String input) {
  try {
     //stack to store opening parenthesis
     Stack<Character> parenStack = new Stack<>();
     
     for(int i=0; i< input.length(); i++) {
        char ch = input.charAt(i);

        //if an opening parenthesis then push to the stack
        if(openingParenSet.contains(ch)) {
             parenStack.push(ch);
        } 

        //for closing parenthesis
        if(matchingParenMap.containsKey(ch)) {
             Character lastParen = parenStack.pop();
             if(lastParen != matchingParenMap.get(ch)) {
                return false;
             } 
        }
     }

     //returns true if the stack is empty else false
     return parenStack.isEmpty();
   }
     catch(StackOverflowException s) {}
     catch(StackUnderflowException s1) {}
     return false;
}
Other implementations of stack methods :
//method to check if the stack is empty
public boolean isEmpty() {
   return size==0;
}

//method to check if the stack is full
public boolean isFull() {
   return size==MAX_SIZE;
}

//method to get the size of the stack
public int getSize() {
   return size;
}
Performance and complexity of matching parenthesis code snippet :
  1. Time complexity = O(N), N = length of input string because the entire string of length N is processed.
  2. Space complexity = O(N), N = number of elements.
  3. push() and pop() operations have constant time complexity i.e. O(1) because irrespective of the input parenthesis it always takes only one operation to push or pop an element from the stack.
  4. isEmpty(), isFull(), getSize() have constant time complexity i.e. O(1) if size variable is maintained, it can be easily checked by comparing size variable with MAX_SIZE of the stack. If size variable is not used then complexity = O(N), N = number of elements, which requires counting the number of elements present in the stack.
Applications of stack:
  1. Implementing undo in any application: In word processor application, color or font can be undo ed. Undo operation is performed by popping the last element of the stack.
  2. Implementing back button in browsers: Keep adding the visited URL’s in the stack. And when you click the back arrow in browser pop an element from the stack and load the previous URL.

Here is the link to my github profile containing the code snippet shown above, Stack data structure in Java.

Please post comments below if you want to share any more information on the above topic discussed. Happy learning..!!

3 thoughts on “java.util.Stack data structure in Java

  1. Alert: A bit lengthy comment.

    Nicely written and conveys most of the things about Stack data structure in a single post *but* to a person who has prior knowledge of Stack. A noob person, who doesn’t know about Stack will find this post significantly difficult to understand.

    I have multiple suggestions to improve this post:

    1. You have given definition very nicely also you have put down possible operations performed by Stack. But, at this
    point the reader of the blog, who supposedly know a very little about Stack, would want to know a little bit about the
    implementation of Stack (e.g how push() or pop() is implemented internally), then only it will make sense to move
    further to solve an example. You may give a link of a page the Stack implementation has already been done.
    e.g. “To learn more about the internal implementation of Stack visit
    https://www.javamadesoeasy.com/2015/01/stacks.html

    2. For the example program for parenthesis matching I suggest following,
    2.1. Code doesn’t look self explanatory, please elaborate it by explaining before the Code snippet.
    2.2. Explain the example or give the a link to say- https://www.geeksforgeeks.org/check-for-balanced-parentheses-
    in-an-expression/.
    2.3 The code snippet should have a bit smarter background and keywords of Java code highlighted with color
    which will make it more readable.
    2.4 A section “Other stack methods:” jumped into middle out of nowhere :). The title of section could be “Internal
    implementation of operations supported by Stack”.
    2.5 Also the code section of “Other stack methods:” doesn’t make any sense given that the reader has no prior
    knowledge of Stack.
    3. What does the section “Performance and complexity of above code snippet:” talks about? Because the code
    snippet just above this section is “Other stack methods:”. Be a bit more descriptive and use the words like “Best
    case”, “average case” and “Worst case” complexity, which will make it look more apparent.
    4. Give few more links(e.g https://www.geeksforgeeks.org/stack-set-2-infix-to-postfix/ etc) and further reading to
    “Other applications of stack” section. You could rename the section name to “Applications of stack”.
    5. Put a pre-requisite section at the very top which briefs about pre-requites like, Java basics and Data structures basics.
    6. Put some keywords at the bottom, which will give your page more priority than other similar pages in google
    indexing.
    7. Final and most important suggestion, put links to more useful posts for each of the sections, which is what could
    make this blog more informative and more useful to the readers and extensible as well. Even experienced
    programmers will find it handy and useful. Moreover, putting links will allow Google crawler
    (https://www.google.com/search/howsearchworks/crawling-indexing/) to index your page at the top in Google search result.

    Happy reading!

    Like

Leave a comment

Design a site like this with WordPress.com
Get started