The ArrayDeque Class

Here is the class, with its fields and constructor:

public class ArrayDeque<T> implements Deque<T> {

  private T[] arr;    // the backing array, used as a circular array
  private int front;
  private int size;

  @SuppressWarnings("unchecked")
  public ArrayDeque() {
    arr = (T[]) new Object[10];
    front = 0;
    size = 0;
  }

  // ... the operations will go here
}

Two small helpers make the formulas easier to read:

private int index(int offset) {
  return (front + offset) % arr.length;
}

private int before(int i) {
  return (i + arr.length - 1) % arr.length;
}

The index helper turns a logical offset from the first end into a physical array index. The before helper moves one slot left, wrapping from 0 to the last index.

The isEmpty operation reads size:

@Override
public boolean isEmpty() {
  return size == 0;
}

The getter methods check that the deque is not empty, then read the item at the correct end:

@Override
public T getFirst() {
  if (isEmpty()) {
    throw new NoSuchElementException();
  }
  return arr[front];
}

@Override
public T getLast() {
  if (isEmpty()) {
    throw new NoSuchElementException();
  }
  return arr[index(size - 1)];
}

removeFirst is ArrayQueue’s dequeue:

@Override
public void removeFirst() {
  if (isEmpty()) {
    throw new NoSuchElementException();
  }
  arr[front] = null;
  front = index(1);
  size--;
}

Removing from the last end clears the last slot and decrements size:

@Override
public void removeLast() {
  if (isEmpty()) {
    throw new NoSuchElementException();
  }
  arr[index(size - 1)] = null;
  size--;
}

Picture a wrapped deque in a capacity-5 array holding 7, 2, 5 in logical order, with front at index 3. removeLast clears the current last slot (index 0, which holds 5) and leaves front at index 3:

┌───┬───┬───┬───┬───┐
│ 5 │ _ │ _ │ 7 │ 2 │
└───┴───┴───┴───┴───┘
  ↑           ↑
last        front
┌───┬───┬───┬───┬───┐
│ _ │ _ │ _ │ 7 │ 2 │
└───┴───┴───┴───┴───┘
              ↑   ↑
            front last

Removing at the last end decrements size, so index(size - 1) now points to the new last item.

After removing the only item, size becomes 0. We do not need to reset front to 0. The front field can be any valid index.