给jdk写注释系列之jdk1.6容器(11):Queue之ArrayDeque源码解析

gy737859 8年前

来自: http://www.importnew.com/17670.html

public interface Queue<E> extends Collection<E> {      // 增加一个元素到队尾,如果队列已满,则抛出一个IIIegaISlabEepeplian异常      boolean add(E e);      // 添加一个元素到队尾并返回true,如果队列已满,则返回false      boolean offer(E e);      // 移除并返回队列头部的元素,如果队列为空,则抛出一个NoSuchElementException异常      E remove();      // 移除并返问队列头部的元素,如果队列为空,则返回null      E poll();      // 返回队列头部的元素,如果队列为空,则抛出一个NoSuchElementException异常      E element();      // 返问队列头部的元素,如果队列为空,则返回null      E peek();  }

看到Queue的定义,有没有发现它和Stack的方法是非常相似的。

但是ArrayDeque并不是一个固定大小的队列,每次队列满了就会进行扩容,除非扩容至超过int的边界,才会抛出异常。所以这里的add和offer几乎是没有区别的。

2.底层存储

 

当然从ArrayDeque的命名就可以看出他的底层是用数组实现的(而LinkedList则是用链表实现的队列),来主要看一下ArrayDeque。

// 底层用数组存储元素      private transient E[] elements;       // 队列的头部元素索引(即将pop出的一个)        private transient int head;       // 队列下一个要添加的元素索引        private transient int tail;       // 最小的初始化容量大小,需要为2的n次幂        private static final int MIN_INITIAL_CAPACITY = 8;

这里需要注意的是MIN_INITIAL_CAPACITY,这个初始化容量必须为2的n次幂。为什么必须要是2的n次幂呢,还记得HashMap中我们的分析吗,HashMap也要求其底层数组的初始容量必须为2的n次幂,还记得当时是基于什么原因吗?不记得话,那就返回去看一下《 给jdk写注释系列之jdk1.6容器(4)-HashMap源码解析 》。那么ArrayDeque这里又是基于什么考虑呢,我们下面再看。

而tail不是最后一个元素的索引,是下一个要添加的元素索引,也就是最后一个元素+1。

3.构造方法

</div> </div>