Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

addFirst method of ArrayDeque Class

The code of addFirst method in java.util.ArrayDeque class is

public void addFirst(E e) {
    if (e == null)
        throw new NullPointerException();
    elements[head = (head - 1) & (elements.length - 1)] = e;
    if (head == tail)
        doubleCapacity();
}

Here, I am not able to understand the meaning of

head = (head - 1) & (elements.length - 1)

Also, Suppose if array size is 10. head is at 0 and tail is at 9(Array is full). In this case, at what index system will do insertion? (My understanding is: if array is full then, first increase its size and then do insertion in the arraySize()-1 index.)

like image 605
Pankz Avatar asked Feb 04 '15 06:02

Pankz


People also ask

What is ArrayDeque class in Java?

ArrayDeque class describes an implementation of a resizable array structure which implements the Deque interface. Array deques has not immutable and can grow as necessary. They are not thread-safe and hence concurrent access by multiple threads is not supported unless explicitly synchronized.

What is ArrayDeque?

An ArrayDeque (also known as an “Array Double Ended Queue”, pronounced as “ArrayDeck”) is a special kind of a growable array that allows us to add or remove an element from both sides. An ArrayDeque implementation can be used as a Stack (Last-In-First-Out) or a Queue(First-In-First-Out).

Is ArrayDeque synchronized?

ArrayDeque does not provide the thread synchronization necessary to ensure that multiple threads do not simultaneously try to access it.


1 Answers

The functionality of the following line is basically (head - 1) MODULO (elements.length), so that subtracting 1 from head results in the maximum possible value instead of -1 when head == 0.

head = (head - 1) & (elements.length - 1)

10 is not valid length of elements, according to the implementation, elements.length is always a power of two. If this were not the case the operation would not work.

Understanding why this works requires knowledge of bit operations. Assuming elements.length == 16 == 00010000b and that the length of values are 8 bits instead of the actual 32 for simplicity's sake:

(elements.length - 1) is used to get a bit mask of ones n bits long, where 2^n is the current length of elements. (elements.length - 1) == 15 == 00001111b in this case.

If head > 0 and head < elements.length (which is a given), then (head - 1) & (elements.length - 1) == (head - 1), as ANDing with 1s does nothing.

If head == 0, head - 1 == -1 == 11111111b. (Two's complement signed integer notation, although you can also view it as a simple integer overflow.) ANDing with the mask (head - 1) & 00001111b == 11111111b & 00001111b == 00001111b == 15, which is the wanted value.

like image 149
Adrian Leonhard Avatar answered Sep 22 '22 09:09

Adrian Leonhard