Well I was wondering about this, so I unzipped Java's source code and took a look. The code was quite confusing to me, especially this addFirst method:

Code:
    /**
     * Inserts the specified element at the front of this deque.
     *
     * @param e the element to add
     * @throws NullPointerException if the specified element is null
     */
    public void addFirst(E e) {
        if (e == null)
            throw new NullPointerException();
        elements[head = (head - 1) & (elements.length - 1)] = e;
        if (head == tail)
            doubleCapacity();
    }
It seems to me that if I call addFirst to the very first insertion in an ArrayDeque, it will get a negative number from head - 1. The binary operator will make sure it goes to elements.length - 1 incase head - 1 returns negative value. But still, what is this code doing inserting the element into an ArrayDeque? How is ArrayDeque playing with its internal array?

Also I dont quite understand where the properties head and tail are initialized. If they share the same value 0 by default, the addFirst() method will call doubleCapacity() right after my very first insertion? Anyway its kinda confusing and I wonder if anyone here doesnt mind explaining a bit on how ArrayDeque works. Id apprecaite this very much.