Implementing addFirst, addLast, and grow

Both adds are ArrayQueue’s enqueue except for where they write the item.

Here is addFirst:

@Override
public void addFirst(T item) {
  if (item == null) {
    throw new IllegalArgumentException();
  }
  if (size == arr.length) {
    grow();
  }
  front = before(front);
  arr[front] = item;
  size++;
}

As in enqueue, the call to grow comes first, here because grow resets front to 0.

Here is addLast:

@Override
public void addLast(T item) {
  if (item == null) {
    throw new IllegalArgumentException();
  }
  if (size == arr.length) {
    grow();
  }
  arr[index(size)] = item;
  size++;
}

The grow helper follows the same pattern as the grow in ArrayQueue:

@SuppressWarnings("unchecked")
private void grow() {
  T[] bigger = (T[]) new Object[arr.length * 2];
  for (int i = 0; i < size; i++) {
    bigger[i] = arr[index(i)];
  }
  arr = bigger;
  front = 0;
}

The only change is that the loop reads through index(i).

That completes ArrayDeque.