Back to Java
2026-01-067 min read

Java - ArrayDeque

Learn Java - ArrayDeque step by step with clear examples and exercises.

Why This Matters

In Java programming, understanding the ArrayDeque class is crucial for writing efficient code that can handle complex problems with ease. Mastering ArrayDeque can help you avoid common programming pitfalls and write more effective solutions.

Prerequisites

To fully grasp this lesson, you should have a good understanding of Java basics:

  1. Familiarity with Java syntax and data types
  2. Knowledge of classes, methods, and objects
  3. Understanding of collections like List, Queue, Deque, and Map
  4. Experience with arrays and linked lists
  5. Awareness of exception handling (specifically NullPointerException)
  6. Familiarity with thread safety and synchronization concepts (optional but recommended)
  7. Comfortable working with generic types in Java
  8. Knowledge of fundamental data structures like stacks and queues

Core Concept

ArrayDeque Overview

The ArrayDeque class is part of the Java Util package (java.util) and implements both the Deque interface and the Queue interface. It provides a resizable-array implementation that supports adding, removing, and iterating over elements from either end (front or rear).

Key Features

  1. Resizable: ArrayDeques have no capacity restrictions, allowing them to grow as needed to accommodate more elements.
  2. Faster than Stack and LinkedList: ArrayDeques offer faster performance due to direct memory access when compared to Stack and LinkedList.
  3. Null Elements Prohibited: Null elements are not allowed in ArrayDeques, ensuring the data structure remains consistent and error-free.
  4. Serializable and Cloneable: ArrayDeques can be serialized and cloned, making them useful for storing and transferring data between different parts of a program or across networks.
  5. Supports Iterator Interface: ArrayDeques provide an iterator that implements the Iterator interface, allowing easy traversal of the deque's elements.
  6. Thread-Unsafe: ArrayDeque is not thread-safe and should not be used for concurrent access without proper synchronization (e.g., using Collections.synchronizedDeque()).
  7. Offers additional methods like peek(), offer(), poll(), and remove() for more flexible manipulation of elements.

Declaration and Constructors

The declaration for the Java ArrayDeque class is as follows:

public class ArrayDeque<E> extends AbstractCollection<E> implements Serializable, Cloneable, Iterable<E>, Collection<E>, Deque<E>, Queue<E>

Here `` represents the generic type of elements in the deque. For example, if you're building an ArrayDeque of Integers, you would initialize it as:

Deque<Integer> objDeque = new ArrayDeque<>();

ArrayDeque offers three constructors:

  1. ArrayDeque(): Creates an empty ArrayDeque with an initial capacity sufficient to hold 16 elements.
  2. ArrayDeque(Collection<? extends E> c): Creates a deque containing the elements of the specified collection.
  3. ArrayDeque(int numElements): Initializes the deque with the specified number of elements, using the provided initial capacity.

Worked Example

Let's explore an example that demonstrates how to use ArrayDeque for implementing a simple queue data structure and handling common mistakes.

import java.util.ArrayDeque;
import java.util.Collections;

public class Main {
public static void main(String[] args) {
// Create an empty ArrayDeque to represent our queue
Deque<Integer> myQueue = new ArrayDeque<>();

// Add elements to the queue
myQueue.addFirst(10);
myQueue.addFirst(20);
myQueue.addLast(30);

System.out.println("Initial Queue: " + myQueue); // Output: [20, 10, 30]

// Remove and print the front element (head) of the queue
try {
System.out.println("Remove and Print Head: " + myQueue.removeFirst()); // Output: 20
} catch (NullPointerException e) {
System.err.println("Error: Cannot remove from an empty deque.");
}
System.out.println("Updated Queue: " + myQueue); // Output: [10, 30]

// Remove and print the rear element (tail) of the queue
try {
System.out.println("Remove and Print Tail: " + myQueue.removeLast()); // Output: 30
} catch (NullPointerException e) {
System.err.println("Error: Cannot remove from an empty deque.");
}
System.out.println("Updated Queue: " + myQueue); // Output: [10]
}
}

Common Mistakes

  1. Adding a null element: ArrayDeque does not allow adding a null element, resulting in a NullPointerException. Always check for null values before adding them to an ArrayDeque or handle exceptions accordingly.
  2. Concurrent access without synchronization: Since ArrayDeque is not thread-safe, it cannot be accessed concurrently by multiple threads without proper synchronization. Use Collections.synchronizedDeque() or other synchronized collection implementations for such scenarios.
  3. Misusing the size method: The size() method returns the number of elements in the deque, but when the deque is empty, it still returns 0 instead of -1 (like an array). Be aware of this difference when comparing sizes or iterating over collections.
  4. Forgetting to import java.util package: Always remember to import the java.util package to use ArrayDeque.
  5. Not handling empty deque exceptions: When removing elements from an empty deque, a NoSuchElementException may occur. It's essential to handle these exceptions or check for an empty deque before performing operations that could lead to such exceptions.
  6. Using ArrayDeque as a thread-safe data structure without proper synchronization: As mentioned earlier, ArrayDeque is not thread-safe and should be used with caution when dealing with concurrent access.
  7. Ignoring the peek(), offer(), poll(), and remove() methods: These methods provide additional flexibility for manipulating elements in the deque. Familiarize yourself with their usage to make the most of ArrayDeque.
  8. Not considering the performance impact of frequent resizing: While ArrayDeques are resizable, frequent resizing can have a negative impact on performance. Be mindful of this when using ArrayDeques in your code.

Practice Questions

  1. Implement a simple implementation of a LIFO (Last-In, First-Out) stack using ArrayDeque.
  2. Write a program that uses ArrayDeque to implement a priority queue where elements with lower values are processed first.
  3. Given an ArrayDeque containing integers 10, 20, 30, and 40, write a one-liner to print the second element from the rear of the deque using the getLast() method.
  4. Implement a thread-safe version of ArrayDeque by synchronizing access to the deque using Collections.synchronizedDeque().
  5. Write a program that demonstrates the difference between the size and isEmpty methods when dealing with an empty ArrayDeque.
  6. Explore the use of the peek(), offer(), poll(), and remove() methods in various scenarios to understand their functionality better.
  7. Investigate the performance impact of resizing an ArrayDeque under different conditions, such as adding and removing elements at both ends or only one end.

Common Mistakes

  1. Adding a null element: Adding a null element to an ArrayDeque will result in a NullPointerException. To avoid this, always check for null values before adding them to the deque.
  2. Concurrent access without synchronization: Since ArrayDeque is not thread-safe, it cannot be accessed concurrently by multiple threads without proper synchronization. Use Collections.synchronizedDeque() or other synchronized collection implementations for such scenarios.
  3. Misusing the size method: The size() method returns the number of elements in the deque, but when the deque is empty, it still returns 0 instead of -1 (like an array). Be aware of this difference when comparing sizes or iterating over collections.
  4. Forgetting to import java.util package: Always remember to import the java.util package to use ArrayDeque.
  5. Not handling empty deque exceptions: When removing elements from an empty deque, a NoSuchElementException may occur. It's essential to handle these exceptions or check for an empty deque before performing operations that could lead to such exceptions.
  6. Using ArrayDeque as a thread-safe data structure without proper synchronization: As mentioned earlier, ArrayDeque is not thread-safe and should be used with caution when dealing with concurrent access.
  7. Ignoring the peek(), offer(), poll(), and remove() methods: These methods provide additional flexibility for manipulating elements in the deque. Familiarize yourself with their usage to make the most of ArrayDeque.
  8. Not considering the performance impact of frequent resizing: While ArrayDeques are resizable, frequent resizing can have a negative impact on performance. Be mindful of this when using ArrayDeque in your code.
  9. Adding elements to a full deque without resizing: If you try to add an element to a full deque without resizing, the deque will throw an ArrayIndexOutOfBoundsException. To avoid this, either provide a larger initial capacity or allow for dynamic resizing when necessary.
  10. Iterating over an empty deque: Iterating over an empty deque using the iterator method will return an empty iterator. Be aware of this and check for an empty deque before iterating to avoid NoSuchElementException.

FAQ

Q: Can I add null elements to an ArrayDeque?

A: No, adding a null element to an ArrayDeque will result in a NullPointerException.

Q: Is ArrayDeque thread-safe?

A: No, ArrayDeque is not thread-safe and should be used with caution when dealing with concurrent access. Use Collections.synchronizedDeque() or other synchronized collection implementations for such scenarios.

Q: What happens if I try to add an element to a full deque without resizing?

A: If you try to add an element to a full deque without resizing, the deque will throw an ArrayIndexOutOfBoundsException. To avoid this, either provide a larger initial capacity or allow for dynamic resizing when necessary.

Q: How does ArrayDeque handle empty deques?

A: When dealing with an empty deque, methods like removeFirst(), removeLast(), and iterating over the deque using the iterator method may throw exceptions. It's essential to handle these exceptions or check for an empty deque before performing operations that could lead to such exceptions.

Q: What is the difference between the size() and isEmpty() methods in ArrayDeque?

A: The size() method returns the number of elements in the deque, but when the deque is empty, it still returns 0 instead of -1 (like an array). The isEmpty() method checks if the deque contains no elements and returns a boolean value.

Java - ArrayDeque | Java | XQA Learn