在上一篇博客 Java容器之LinkedList源码分析(LinkedList到底是单链表还是双链表?) 分析了LinkedList
容器的源码,LinkedList
实现了Deque
接口,所以它不但是一个List
容器,而且还是一个双端队列
容器,并且是基于双链表实现。在此篇博客,将分析基于(循环)数组实现的双端队列
容器——ArrayDeque
。
注明:以下源码分析都是基于jdk 1.8.0_221
版本
Java容器之ArrayDeque源码分析目录
一、ArrayDeque
容器概述
ArrayDeque
类的声明如下:
public class ArrayDeque<E> extends AbstractCollection<E>
implements Deque<E>, Cloneable, Serializable
Java
中的ArrayDeque
容器实现了Deque
接口,所以它是一个双端队列
(队头
、队尾
都可以进行出队
、入队
)容器,并且是底层是通过(循环)数组来存放数据。Java
中的LinkedList
容器也实现了Deque
接口,不过底层是通过维护链表保存数据。
二、ArrayDeque
类的主要属性
/**
* 循环数组
*/
transient Object[] elements; // non-private to simplify nested class access
/**
* 队头对应的下标
*/
transient int head;
/**
* 队尾对应的下标
*/
transient int tail;
/**
* 数组最短的长度(数组的长度需要保持为2的幂,主要是将求余操作转换为移位操作)
*/
private static final int MIN_INITIAL_CAPACITY = 8;
三、ArrayDeque
类的构造器
/**
* 数组默认初始化长度为16
*/
public ArrayDeque() {
elements = new Object[16];
}
/**
* 指定数组的长度
*/
public ArrayDeque(int numElements) {
// 不过数组的长度需要保持为2的次幂,调用allocateElements方法初始化(后面有介绍这个方法)
allocateElements(numElements);
}
/**
* 复制构造方法
*/
public ArrayDeque(Collection<? extends E> c) {
// 先初始化数组,最小长度为c.size(不过仍然需要转换为不必它小的最小2的次幂)
allocateElements(c.size())