ArrayDeque是使用数组实现的双端队列,同时亦是一个循环队列,它不允许值为null。
存储结构
1 | transient Object[] elements; |
构造方法
- 默认的构造方法:默认容量为16。
1 | // 默认的容量为16 |
- 指定元素个数
1 | public ArrayDeque(int numElements) { |
1.allocateElements方法用于计算队列的容量并初始化,其源码如下:
1 | private void allocateElements(int numElements) { |
2.allocateElements方法调用了calculateSize方法,其与HashMap中的tableSizeFor方法类似,都是用于寻找大于numElements的最小的2的幂数,源码如下:
1 | private static int calculateSize(int numElements) { |
3.声明MIN_INITIAL_CAPACITY的源码如下:
1 | // 容量必须为2的幂数 |
添加元素
ArrayDeque不允许值为null。
在队尾添加
1 | public boolean offer(E e) { |
注意这里的条件判断:(tail = (tail + 1) & (elements.length - 1)) == head
原本应该写成(tail = (tail + 1) % elements.length == head
,但这里使用位运算代替了取模。
由于人为地规定ArrayDeque的容量必须为2的幂数。
这也是为什么在指定容量的构造方法中调用了calculateSize方法计算大于给定容量的最小的2的幂数。
在队首添加
1 | public boolean offerLast(E e) { |
扩容操作
当队列已满时,将进行扩容,新的容量为原来的2倍。
1 | private void doubleCapacity() { |
查询操作
取队首
1 | public E peek() { |
取队尾
由于tail指向队尾元素的下一个位置,因此,队尾元素的索引 = (tail - 1 + elements.length) % elements.length。
1 | "unchecked") ( |
删除操作
删除队首
1 | public E poll() { |
删除队尾
1 | public E pollLast() { |
元素个数
在循环队列,元素的个数 = (tail - head + elements.length) % elements.length。
1 | public int size() { |
判空
1 | public boolean isEmpty() { |