# Java Notes: ArrayDeque<E>

`java.util.ArrayDeque<E>` implements a double-ended queue, which allows efficient insertion and deletion at both ends. This an excellent choice for stacks and queues.

An ArrayDeque has these characteristics:

- Stack or queue. Supports operations to efficiently add, examine, or remove elements from either end.
- Automatically expands as data is added to either the front or back. No capacity limit.
- Good performance
  - Adding, examining, or deleting and element at either end of an ArrayDeque is O(1).
  - Generally faster than Stack.
  - Generally faster than LinkedList for queue operations.
- ArrayDeque implements Iterable, so can be traversed using a foreach loop or iterator. It also provides a `descendingIterator()` method for iterating in reverse order.
- As with the other collections classes, only Object types are supported.
- No indexed access is permitted.
- No sorting is possible -- deques are not lists.

## Terminology

What are the ends called? The terminology of stacks and queues and lists is not standardized, so you'll see various terms for the ends.

- Front = head = start = first.
- Back = tail = end = last.

## Common ArrayDeque methods and constructors

Here are some of the most useful ArrayDeque methods. Assume these declarations. Note that `E` is the notation for the type of an element in a collection.

       int i;
       boolean b;
       ArrayDeque<E> a;
       E e;
       Iterator<E> iter;
       E[] earray;
       Object[] oarray;

Result | Method | Description
--- | --- | ---
Constructors
`a =` | `new ArrayDeque<E>()` | Creates ArrayDeque with initial default capacity.
`a =` | `new ArrayDeque<E>(cap)` | Creates ArrayDeque with initial int capacity cap.
`a =` | `new ArrayDeque<E>(coll<E>)` | Creates ArrayDeque from the Collection coll.
Operations on the front (head, start, first)
`` | `a.addFront(e)` | adds `e` to the front of ArrayDeque `a`
`b =` | `a.offerFirst(e)` | Same as addFront. With capacity limited deques (not ArrayDeque) can return false.
`e =` | `a.getFirst()` | Returns, but does not remove, first element. Throws exception if deque is empty.
`e =` | `a.element()` | Same as getFirst.
`e =` | `a.peekFirst()` | Same as getFirst, but returns null if deque is empty.
`e =` | `a.peek()` | Same as peekFirst.
`e =` | `a.removeFirst()` | Returns and removes first element. Throws exception if deque is empty.
`e =` | `a.remove()` | Same as pollFirst.
`e =` | `a.pollFirst()` | Returns and removes first element. Returns null if deque is empty.
`e =` | `a.poll()` | Same as pollFirst.
`e =` | `a.pop()` | Same as removeFirst.
`e =` | `a.push(e)` | Same as addFront.
Operations on the back (tail, end, last)
`` | `a.addLast(e)` | adds `e` to the end of ArrayDeque `a`
`` | `a.add(e)` | Same as addLast.
`b =` | `a.offerLast(e)` | Same as addLast. With capacity limited deques (not ArrayDeque) can return false.
`b =` | `a.offer(e)` | Same as offerLast.
`e =` | `a.getLast()` | Returns, but does not remove, last element. Throws exception if deque is empty.
`e =` | `a.peekLast()` | Same as getLast, but returns null if deque is empty.
`e =` | `a.removeLast()` | Returns and removes last element. Throws exception if deque is empty.
`e =` | `a.pollLast()` | Returns and removes last element. Returns null if deque is empty.
Turning into an array
`oarray =` | `a.toArray()` | Returns values in array of objects.
`earray =` | `a.toArray(E[])` | The array parameter should be of the E class. Returns values in that array (or a larger array is allocated if necessary).
Iterators
`iter =` | `a.iterator()` | Returns an Iterator for forward traversal.
`iter =` | `a.descendingIterator()` | Returns an Iterator for backward traversal.
Searching
`b =` | `a.contains(e)` | Returns true if ArrayDeque `a` contains `e`
`b =` | `a.removeFirstOccurrence(e)` | Removes `e` from deque starting at beginning. Returns true if successful.
`b =` | `a.removeLastOccurrence(e)` | Removes `e` from deque starting at end. Returns true if successful.
`b =` | `a.remove(e)` | Same as `removeFirstOccurrence()`.
Removing elements
Other
`i =` | `a.size()` | Returns the number of elements in ArrayDeque `a`.
`` | `a.clear()` | removes all elements from ArrayDeque `a`

## To get successive elements from an ArrayDeque - Several ways

Use either the foreach loop or an Iterator.

1. foreach loop. This is fast and works for all kinds of lists, but is not entirely flexible (only sequential forward with no deletions, additions, or multiple references). This should be your first choice in programming. Works efficiently with both ArrayDeque and LinkedList.

       ArrayDeque<String> a = new ArrayDeque<String>();
       . . .
       for (String s : a) {
           System.out.println(s);
       }

2. `Iterator<E>` - Allows simple forward traversal. Can be used for the largest number of other kinds of data structures.

   This example uses an Iterator to print all elements (Strings) in an ArrayDeque. It uses `hasNext()`, which returns true if there are more elements, and `next()`, which returns the next element. Works with both ArrayDeque and LinkedList.

       for (Iterator<String> iter = a.iterator(); iter.hasNext();  ) {
           System.out.println(iter.next());
       }

3. `ListIterator<E>` - Allows traversal of the ArrayDeque, but it is more general than a simple Iterator, allowing inserts and deletes (although both are very slow for an ArrayDeque). It also allows bidirectional traversal. Works efficiently with both ArrayDeque and LinkedList.