Queues are important data structures in programming that follow the First-In, First-Out (FIFO) principle, meaning that the first item added to the queue is the first one removed. Queues are useful for handling data sequentially, such as printing documents, processing requests, or simulating waiting lines. In this blog post, you will learn how to implement queues in Java using different built-in classes, such as Queue, LinkedList, and ArrayDeque. You will also learn how to create a Maven project to develop and test your queue 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/queue
Creating a Maven Project
Let’s create a our project
- Open your terminal and navigate to the directory where you want to create your project.
- Run the following command to generate a new Maven project:
mvn archetype:generate -DgroupId=com.makariev.examples.core -DartifactId=queue -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:
- Delete the
src/main/java/com/makariev/examples/core/App.java
file. - Delete the
src/test/java/com/makariev/examples/core/AppTest.java
file. - Open the
pom.xml
file and delete the JUnit 3 dependency (junit:junit). - 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 Queue in Java
Now, let’s create a simple Java program that demonstrates the use of a Queue, LinkedList, and ArrayDeque, and how they adhere to the FIFO principle.
Queue, LinkedList, and ArrayDeque Example
Create a new Java class, QueueExampleTest.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.Queue;
public class QueueExampleTest {
@Test
void testQueueLinkedListArrayDeque() {
// Create a queue
Queue<String> queue = new LinkedList<>();
queue.add("Alan Turing");
queue.add("Grace Hopper");
queue.add("Linus Torvalds");
queue.add("Ada Lovelace");
queue.add("Donald Knuth");
// Check the size of the queue
assertThat(queue.size()).isEqualTo(5);
// Poll elements from the queue and check their order (FIFO)
assertThat(queue.poll()).isEqualTo("Alan Turing");
assertThat(queue.poll()).isEqualTo("Grace Hopper");
assertThat(queue.poll()).isEqualTo("Linus Torvalds");
assertThat(queue.poll()).isEqualTo("Ada Lovelace");
assertThat(queue.poll()).isEqualTo("Donald Knuth");
// Create a LinkedList (used as a queue)
LinkedList<String> linkedList = new LinkedList<>();
linkedList.addLast("Alan Turing");
linkedList.addLast("Grace Hopper");
linkedList.addLast("Linus Torvalds");
linkedList.addLast("Ada Lovelace");
linkedList.addLast("Donald Knuth");
// Check the size of the linked list (queue)
assertThat(linkedList.size()).isEqualTo(5);
// Remove elements from the linked list (queue) and check their order (FIFO)
assertThat(linkedList.poll()).isEqualTo("Alan Turing");
assertThat(linkedList.poll()).isEqualTo("Grace Hopper");
assertThat(linkedList.poll()).isEqualTo("Linus Torvalds");
assertThat(linkedList.poll()).isEqualTo("Ada Lovelace");
assertThat(linkedList.poll()).isEqualTo("Donald Knuth");
// Create an ArrayDeque (used as a queue)
ArrayDeque<String> arrayDeque = new ArrayDeque<>();
arrayDeque.addLast("Alan Turing");
arrayDeque.addLast("Grace Hopper");
arrayDeque.addLast("Linus Torvalds");
arrayDeque.addLast("Ada Lovelace");
arrayDeque.addLast("Donald Knuth");
// Check the size of the ArrayDeque (queue)
assertThat(arrayDeque.size()).isEqualTo(5);
// Remove elements from the ArrayDeque (queue) and check their order (FIFO)
assertThat(arrayDeque.poll()).isEqualTo("Alan Turing");
assertThat(arrayDeque.poll()).isEqualTo("Grace Hopper");
assertThat(arrayDeque.poll()).isEqualTo("Linus Torvalds");
assertThat(arrayDeque.poll()).isEqualTo("Ada Lovelace");
assertThat(arrayDeque.poll()).isEqualTo("Donald Knuth");
}
}
In this single JUnit 5 test, we demonstrate the use of a Queue, a LinkedList (used as a queue), and an ArrayDeque (used as a queue). We push the names of famous computer scientists onto these data structures, check the size, and then poll the names to verify their order, adhering to the FIFO principle.
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 queue structures in Java. Queues are essential data structures for various programming scenarios, and mastering them is vital for any Java developer.
Happy coding!