看看ArrayDeque源码

以前看了其余实现Deque接口的类,这里再看看ArrayDeque吧,下图能够看到这个类设计的结构层次,其实Deque接口是继承了Queue接口的。用可调整大小的数组实现Deque接口。没有容量限制,他们根据须要增加以支持使用。它们不是线程安全的,在没有外部同步的状况下,它们不支持多线程的并发访问。禁止使用空元素。数组

大多数ArrayDeque操做以常量时间运行。例外包括remove,removeFirstOccurrence,removeLastOccurrence,contains,iterator.remove()和一些批量操做,全部这些都以线性时间运行。安全

此类有三个构造函数,以下图:多线程

ArrayDeque​():构造一个空数组deque,其初始容量16个元素。并发

ArrayDeque​(int numElements):构造一个空数组deque,其初始容量足以容纳指定数量的元素。函数

ArrayDeque​(Collection<? extends E> c):按照集合的迭代器返回的顺序构造一个包含指定集合元素的双端队列。工具

ArrayDeque中的字段主要有 transient Object[] elements,transient int head;,transient int tail;这里看到就是修饰词都是transient,表示类实现了序列化接口,可是该敏感词汇不会被序列化。elements是用来存储元素的;head表示队列的头部,pop()和remove()操做的元素;tail表示下一个元素要添加的位置,好比push(),add()和addLast()要增长的元素。测试

calculateSize和名字表述同样,用于调整队列容量的使用工具,可是有个限制就是2 ^ 30个元素,注释写的颇有趣"good luck"。线程

还有一种扩容测试是变为原来的两倍,这边若是容量太大,会报“sorry,deque too big”的IllegalStateException异常,能够看到扩容就要复制一份原来的元素,这个仍是比较消耗资源的。复制这里用的都是 public static native void arraycopy(Object src,  int  srcPos,Object dest, int destPos,int length);设计

在此双端队列的前面插入指定的元素,addFirst​(E e)。这里由于是使用数组,因此增长队首元素的时候,须要判断元素在的位置,经过移动head的位置,elements[head = (head - 1) & (elements.length - 1)],这与咱们正常看到的队列的第一个元素概念不一样。若是head与tail指向了同一个位置,就须要扩容啦。3d

addLast​(E e):在此双端队列的末尾插入指定的元素。这个与addfist相似,就是要判断队尾的位置,而后是否扩容。

而后咱们看看pollFisrt(),将head位置的元素置为空,而后head+1的位置设置为队首,这里借助了一个变量h;后面的pollLast也是相似的,取tail前一个元素的位置。相似的,getFirst()和getLast()也是经过相同的方式,获取元素。

这里判断size和empty的方式也能够看看,size是经过tail和head的差值计算,虽然多是负数,可是与length-1作了与操做。empty的判断比较简单,就是比较head和tail是否相等。

这里麻烦一点的就是delete操做了,删除某个位置的元素,由于这里按照head和tail的位置,移动tail或者head的位置。

相关文章
相关标签/搜索