What is Stack in Java?

Stacks are essential data structures in programming that follow the Last-In, First-Out (LIFO) principle, meaning that the last item added to the stack is the first one removed. Stacks are useful for managing data efficiently, such as reversing a word, evaluating expressions, or implementing undo/redo operations. In this blog post, you will learn how to implement stacks in Java using different built-in classes, such as Stack, LinkedList and Deque. You will also learn how to create a Maven project to develop and test your stack implementation using JUnit and AssertJ.

Prerequisites

If you don’t already have Maven installed, you can download it from the official Maven website https://maven.apache.org/download.cgi or through SDKMAN https://sdkman.io/sdks#maven

You can clone the https://github.com/dmakariev/examples repository.

git clone https://github.com/dmakariev/examples.git
cd examples/java-core/stack-deque

Creating a Maven Project

Let’s create a our project

  1. Open your terminal and navigate to the directory where you want to create your project.
  2. Run the following command to generate a new Maven project:
    mvn archetype:generate -DgroupId=com.makariev.examples.core -DartifactId=stack-deque -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    

    This command generates a basic Maven project structure with a sample Java class, and the group ID and artifact ID are set as per your requirements.

Deleting Initial Files and Updating Dependencies

To clean up the initial files generated by the Maven archetype and update dependencies, follow these steps:

  1. Delete the src/main/java/com/makariev/examples/core/App.java file.
  2. Delete the src/test/java/com/makariev/examples/core/AppTest.java file.
  3. Open the pom.xml file and delete the JUnit 3 dependency (junit:junit).
  4. Add the JUnit 5 and AssertJ dependencies to the pom.xml file:
<dependencies>
    <!-- JUnit 5 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.10.0</version> <!-- Use the latest version -->
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.10.0</version> <!-- Use the latest version -->
        <scope>test</scope>
    </dependency>
    <!-- AssertJ -->
    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <version>3.24.2</version> <!-- Use the latest version -->
        <scope>test</scope>
    </dependency>
</dependencies>

Implementing Stack and Deque in Java

Now, let’s create a simple Java program that demonstrates the use of both stacks and deques.

Stack and Deque Example

Create a new Java class, StackDequeExampleTest.java, in the src/test/java/com/makariev/examples/core directory with the following content:

package com.makariev.examples.core;

import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;

import java.util.LinkedList;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Stack;

public class StackDequeExampleTest {

    @Test
    void testStackLinkedListDeque() {
        // Create a stack
        final Stack<String> stack = new Stack<>();
        stack.push("Alan Turing");
        stack.push("Grace Hopper");
        stack.push("Linus Torvalds");
        stack.push("Ada Lovelace");
        stack.push("Donald Knuth");

        // Check the size of the stack
        assertThat(stack.size()).isEqualTo(5);

        // Pop elements from the stack and check their order (FILO)
        assertThat(stack.pop()).isEqualTo("Donald Knuth");
        assertThat(stack.pop()).isEqualTo("Ada Lovelace");
        assertThat(stack.pop()).isEqualTo("Linus Torvalds");
        assertThat(stack.pop()).isEqualTo("Grace Hopper");
        assertThat(stack.pop()).isEqualTo("Alan Turing");

        // Create a LinkedList (used as a stack)
        final LinkedList<String> linkedList = new LinkedList<>();
        linkedList.push("Alan Turing");
        linkedList.push("Grace Hopper");
        linkedList.push("Linus Torvalds");
        linkedList.push("Ada Lovelace");
        linkedList.push("Donald Knuth");

        // Check the size of the linked list (stack)
        assertThat(linkedList.size()).isEqualTo(5);

        // Remove elements from the linked list (stack) and check their order (FILO)
        assertThat(linkedList.pop()).isEqualTo("Donald Knuth");
        assertThat(linkedList.pop()).isEqualTo("Ada Lovelace");
        assertThat(linkedList.pop()).isEqualTo("Linus Torvalds");
        assertThat(linkedList.pop()).isEqualTo("Grace Hopper");
        assertThat(linkedList.pop()).isEqualTo("Alan Turing");

        // Create a Deque (used as a stack)
        final Deque<String> deque = new ArrayDeque<>();
        deque.push("Alan Turing");
        deque.push("Grace Hopper");
        deque.push("Linus Torvalds");
        deque.push("Ada Lovelace");
        deque.push("Donald Knuth");

        // Check the size of the deque (stack)
        assertThat(deque.size()).isEqualTo(5);

        // Remove elements from the deque (stack) and check their order (FILO)
        assertThat(deque.pop()).isEqualTo("Donald Knuth");
        assertThat(deque.pop()).isEqualTo("Ada Lovelace");
        assertThat(deque.pop()).isEqualTo("Linus Torvalds");
        assertThat(deque.pop()).isEqualTo("Grace Hopper");
        assertThat(deque.pop()).isEqualTo("Alan Turing");
    }
}

In this single JUnit 5 test, we demonstrate the use of both stacks and deques. We push the names of famous computer scientists onto the data structures, check the size, and then pop the names to demonstrate that they come out in reverse order.

Running the Test

To run the test, execute the following command in the project’s root directory:

mvn test

JUnit 5 and AssertJ will execute the test, and you should see output indicating whether the test passed or failed.

Conclusion

In this blog post, we’ve explored the concept of stack and deque data structures in Java. Stacks and deques are essential data structures for various programming scenarios, and mastering them is vital for any Java developer.


Coffee Time!

Happy coding!

Share: Twitter LinkedIn