Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the class ArrayDeque not extend from AbstractQueue?

Why is the class ArrayDeque defined as

public class ArrayDeque<E> extends AbstractCollection<E>
                       implements Deque<E>, Cloneable, Serializable

and not as

public class ArrayDeque<E> extends AbstractQueue<E>
                       implements Deque<E>, Cloneable, Serializable

If you look at the following diagram (which has errors, the relation of ArrayDeque to Set is completely wrong) it would make sense that ArrayDeque would inherit from AbstractQueue since it implements the Queue interface indirectly trough the Deque interface.

enter image description here
(source: academic.ru)

like image 271
Mirco Widmer Avatar asked Jul 30 '26 15:07

Mirco Widmer


2 Answers

One of the jsr166 maintainers posted on the OpenJDK core-libs:

I don't think of ArrayDeque as a queue/deque at all. We just have two fundamental data structures here (ArrayList (ordinary resizable array) and ArrayDeque (circular resizable array)) both of which can implement List and Queue in reasonable ways, and ArrayDeque can additionally implement Deque.

Extending AbstractCollection and implementing Deque is consistent with that view.

It also is a conservative move because it would allow future versions of ArrayDeque to extend AbstractList to implement most of List interface. This would only happen if it is considered legal and or desirable to implement both List and Queue due to conflicting equals/hashCode contracts.

like image 107
jmehrens Avatar answered Aug 02 '26 04:08

jmehrens


ArrayDeque can be used as double ended queue, stack, and linked list. I think its more of a design decision. Here, in ArrayDeque, we need to be more specific while adding/removing elements. For eg.

[ArrayDeque.java]
    public boolean add(E e) {
        addLast(e);
        return true;
    }
[AbstractQueue.java]
public boolean add(E e) {
        if (offer(e))
            return true;
        else
            throw new IllegalStateException("Queue full");
    }

Since deque is double ended, we need to be specific where we are adding the element.

Another design consideration could be to reduce the call stack. If you inherit AbstractQueue, it will increase the function call stack with no extra benefit.

Eg.,

Now,

add() -> addLast()

If it inherits AbstractQueue,

add() -> offer() -> offerLast() -> addLast()

Also, by not inheriting AbstractQueue, we are able to reuse small chunks of add, remove operations for different data structures(Queue, Stack, and Linked List) implemented in ArrayDeque.

Finally, Joshua Bloch (author of this API) knows better :)

like image 27
Omkar Shetkar Avatar answered Aug 02 '26 05:08

Omkar Shetkar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!