一、ArrayDeque数组队列
=====================================================
【先进先出】结构
形象图
买火车票(网上订的不算),排队打饭(插队的不讲究)都是这种状态。
public class ArrayDeque<E> extends AbstractCollection<E>
implements Deque<E>, Cloneable, Serializable{
//The array in which the elements of the deque are stored
private transient E[] elements;//数组
//The index of the element at the head of the deque
private transient int head;//队列头
//The index at which the next element would be added to the tail of the deque
private 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;//初始化数组的最小容量
}
//初始化,容量为16public ArrayDeque() {
elements = (E[]) new Object[16];
}
数组结构
想象两个指针,一个指向队头,一个指向队尾,人队是从队尾入的,出队是从队头出的。
1.add()
public boolean add(E e) {
addLast(e);
return true;
}
public void addLast(E e) {
if (e == null)
throw new NullPointerException();
elements[tail] = e; //
if ( (tail = (tail + 1) & (elements.length - 1)) == head)
doubleCapacity();//扩容,增加一倍容量double
}
private void doubleCapacity() {
int p = head;
int n = elements.length;
int r = n - p; // number of elements to the right of p
int newCapacity = n << 1;//相当于*2,扩容一倍
if (newCapacity < 0)
throw new IllegalStateException("Sorry, deque too big");
Object[] a = new Object[newCapacity];
System.arraycopy(elements, p, a, 0, r);
System.arraycopy(elements, 0, a, r, p);
elements = (E[])a;
head = 0;
tail = n;
}
扩容扩容时会消除已经出队(remove掉)的元素占据的空间,如上图:
入队(a,b,c,d,e),然后出队(a,b,c),再入队(f直到p),add(p)后,队列满了,会扩容doubleCapacity(),
System.arraycopy(elements, p, a, 0, r);显示为上图
elements数组的3--15(数组下标index)复制到a数组的0-12
2.remove()
public E remove() {
return removeFirst();
}
public E removeFirst() {
E x = pollFirst();
if (x == null)
throw new NoSuchElementException();
return x;
}
public E pollFirst() {
int h = head;
E result = elements[h]; // Element is null if deque empty
if (result == null)
return null;
elements[h] = null; // Must null out slot
head = (h + 1) & (elements.length - 1);//头指针后移
return result;
}