Java Stack Class

In Java, the Stack class is a part of the java.util package and represents a Last-In-First-Out (LIFO) stack of objects. A stack is a simple yet powerful data structure used to store and manage elements in a specific order. It operates with two primary operations: pushing and popping elements. The Stack class in Java extends the Vector class and provides methods that allow you to push elements to the stack, pop them off, and peek at the top element without removing it.


What is a Java Stack?

A stack is a collection of elements that follows the LIFO (Last-In-First-Out) principle. This means the last element added to the stack is the first one to be removed. The two primary operations associated with a stack are:

  • Push: Adds an element to the top of the stack.
  • Pop: Removes the top element from the stack.
  • Peek: Returns the top element without removing it.

Stacks are widely used in various applications, such as undo operations in text editors, expression evaluation, and even managing recursive function calls in programming.


Java Stack Class: Key Features

  • Inheritance: The Stack class extends Vector and thus inherits its methods for dynamic array resizing.
  • Thread-Safety: While Stack is synchronized and thread-safe, this synchronization comes at the cost of performance. For non-concurrent applications, you may consider alternatives like ArrayDeque.
  • LIFO Order: The stack follows the LIFO principle, ensuring that the most recently added element is the first to be removed.

Common Methods in Java Stack Class

Here are some of the most commonly used methods of the Stack class:

  • push(E item): Adds an item to the top of the stack.
  • pop(): Removes and returns the top item of the stack.
  • peek(): Returns the top element without removing it.
  • empty(): Checks if the stack is empty.
  • search(Object o): Returns the 1-based position of an element in the stack (returns -1 if the element is not found).

Using Java Stack Class: Code Examples

Creating a Stack and Pushing Elements

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        // Create a new stack of integers
        Stack<Integer> stack = new Stack<>();

        // Push elements onto the stack
        stack.push(10);
        stack.push(20);
        stack.push(30);

        // Display the stack
        System.out.println("Stack: " + stack);
    }
}

Output:

Stack: [10, 20, 30]

Popping Elements from the Stack

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();

        // Push elements
        stack.push(10);
        stack.push(20);
        stack.push(30);

        // Pop the top element
        Integer poppedElement = stack.pop();
        System.out.println("Popped Element: " + poppedElement);

        // Display the remaining stack
        System.out.println("Remaining Stack: " + stack);
    }
}

Output:

Popped Element: 30
Remaining Stack: [10, 20]

Peeking the Top Element

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<>();

        // Push elements onto the stack
        stack.push("Apple");
        stack.push("Banana");
        stack.push("Cherry");

        // Peek at the top element without removing it
        String topElement = stack.peek();
        System.out.println("Top Element: " + topElement);

        // Display the stack
        System.out.println("Stack: " + stack);
    }
}

Output:

Top Element: Cherry
Stack: [Apple, Banana, Cherry]

Checking if the Stack is Empty

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();

        // Push elements
        stack.push(1);
        stack.push(2);

        // Check if the stack is empty
        System.out.println("Is the stack empty? " + stack.empty());

        // Pop elements
        stack.pop();
        stack.pop();

        // Check again if the stack is empty
        System.out.println("Is the stack empty? " + stack.empty());
    }
}

Output:

Is the stack empty? false
Is the stack empty? true

Searching for an Element in the Stack

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<>();

        // Push elements onto the stack
        stack.push("A");
        stack.push("B");
        stack.push("C");

        // Search for an element
        int position = stack.search("B");
        System.out.println("Position of 'B': " + position);  // 2

        position = stack.search("D");
        System.out.println("Position of 'D': " + position);  // -1 (not found)
    }
}

Output:

Position of 'B': 2
Position of 'D': -1

When to Use the Stack Class

While the Stack class in Java is useful for many applications, it is somewhat outdated and rarely used in modern Java programming. For most use cases, ArrayDeque or LinkedList is preferred, especially for non-concurrent environments. However, Stack is still valuable for scenarios where you need a simple LIFO structure, such as:

  • Expression Evaluation: Stacks are used in evaluating mathematical expressions, particularly in infix, postfix, and prefix notations.
  • Undo/Redo operations: Many applications like text editors use stacks to implement undo and redo functionality.
  • Recursive Function Calls: The call stack in recursion is essentially a stack data structure used by the system to manage function calls.

Stack vs. Other Data Structures

  • ArrayDeque: A more modern implementation of a deque (double-ended queue), which is faster than Stack when used for LIFO operations because it avoids synchronization overhead.
  • LinkedList: Offers similar functionality as Stack, with slightly more flexibility, but lacks the synchronization offered by Stack.
  • ArrayList: While not intended for LIFO operations, it can still be used, but its performance might be slower for stack-based operations due to its resizing mechanism.