1.ArrayDeque双端队列,jdk中util包中无ArrayQueue的类实现,在com.sun.jmx.remote.internal中才有ArrayQueue队列的实现。
ArrayDeque双端队列方法有,队列头部插入addFirst,头部移除pollFirst,尾部插入addLast,尾部移除元素pollLast
public class ArrayDeque<E> extends AbstractCollection<E>
implements Deque<E>, Cloneable, Serializable
{
/**
* The array in which the elements of the deque are stored.
* The capacity of the deque is the length of this array, which is
* always a power of two. The array is never allowed to become
* full, except transiently within an addX method where it is
* resized (see doubleCapacity) immediately upon becoming full, 队列永远不会满,达到限制后会自动按照双倍容量扩容
* thus avoiding head and tail wrapping around to equal each
* other. We also guarantee that all array cells not holding 队列中每个元素不能为null
* deque elements are always null.
*/
transient Object[] elements; // non-private to simplify nested class access //队列数据
/**
* The index of the element at the head of the deque (which is the
* element that would be removed by remove() or pop()); or an
* arbitrary number equal to tail if the deque is empty.
*/
transient int head; //队列头部指针
/**
* The index at which the next element would be added to the tail
* of the deque (via addLast(E), add(E), or push(E)).
*/
transient int tail; //队列尾部指针
/**
* The minimum capacity that we'll use for a newly created deque.
* Must be a power of 2.
*/
private static final int MIN_INITIAL_CAPACITY = 8; //队列最小容量8
双端队列头部入队列
/**
* Inserts the specified element at the front of this deque.
*
* @param e the element to add
* @throws NullPointerException if the specified element is null
*/
public void addFirst(E e) { //双端队列头部插入元素
if (e == null) // head tail
throw new NullPointerException(); //0 0 0 0 0 0 0 0 0 0 0 0 0
elements[head = (head - 1) & (elements.length - 1)] = e; //头部添加元素,head向左移动
if (head == tail) //双端队列已满,两倍容量扩容
doubleCapacity();
}
尾部入队列
/**
* Inserts the specified element at the end of this deque.
*
* <p>This method is equivalent to {@link #add}.
*
* @param e the element to add
* @throws NullPointerException if the specified element is null
*/
public void addLast(E e) { //双端队列尾部追加元素
if (e == null)
throw new NullPointerException();
elements[tail] = e; //tail
if ( (tail = (tail + 1) & (elements.length - 1)) == head) //tail尾指针向后移动
doubleCapacity(); //两倍元素扩容
}
头部出队列
public E pollFirst() { //双端队列头部出队列
final Object[] elements = this.elements;
final int h = head;
@SuppressWarnings("unchecked")
E result = (E) elements[h]; //读取队列head头部元素
// Element is null if deque empty
if (result != null) {
elements[h] = null; // Must null out slot
head = (h + 1) & (elements.length - 1); //队列头部指针head向后移动,有效元素个数减1
}
return result;
}
尾部出队列
public E pollLast() { //双端队列尾部出队列
final Object[] elements = this.elements;
final int t = (tail - 1) & (elements.length - 1);//队列尾部指针tail向左移动,有效元素个数-1
@SuppressWarnings("unchecked")
E result = (E) elements[t]; //读取队列尾部数据
if (result != null) { //获取到了该元素
elements[t] = null; //该队列元素置null
tail = t; //tail指针向左移动
}
return result;
}
读取队列头部元素
/**
* @throws NoSuchElementException {@inheritDoc}
*/
public E getFirst() { //读取双端队列队列头部元素
@SuppressWarnings("unchecked")
E result = (E) elements[head];
if (result == null)
throw new NoSuchElementException();
return result;
}
读取队列尾部元素
/**
* @throws NoSuchElementException {@inheritDoc}
*/
public E getLast() { //读取双端队列尾部元素
@SuppressWarnings("unchecked")
E result = (E) elements[(tail - 1) & (elements.length - 1)]; //尾部元素
if (result == null)
throw new NoSuchElementException();
return result;
}