ArrayDeque
雙端隊列,表示能夠添加元素到(或刪除,獲取)隊列頭也能夠添加元素到(或刪除,獲取)隊列尾java
類中定義成員變量,一個數組和兩個int數組
transient Object[] elements; transient int head; transient int tail;
數據結構比較清晰,就是一個數組,head指向隊列的頭,tail指向隊列的尾數據結構
數組定義要求數組的容量爲2的n次冪設計
先看刪除邏輯,由於比較簡單,實現以下code
public E poll() { if (size == 0) // 隊列爲空 return null; int s = --size; modCount++; // 數組中第一個爲隊列頭 E result = (E) queue[0]; E x = (E) queue[s]; queue[s] = null; if (s != 0) // 隊列非空時,重排剩下的元素 siftDown(0, x); return result; }
在隊頭和隊尾添加的邏輯基本一致,這裏以在隊列尾添加元素績進行分析對象
public void addLast(E e) { if (e == null) // 不支持向隊列中塞入null對象 throw new NullPointerException(); elements[tail] = e; if ( (tail = (tail + 1) & (elements.length - 1)) == head) { // tail 後移一位,若tail長度超過數組長度,則tail轉到數組頭 // 上面的與操做等價於對數組長度進行求餘 // 若tail和head相等,則表示數組內容填充滿,須要擴容 doubleCapacity(); } } // 數組擴容方法 private void doubleCapacity() { assert head == tail; int p = head; int n = elements.length; int r = n - p; // number of elements to the right of p // 新的容量爲原來的兩倍 int newCapacity = n << 1; if (newCapacity < 0) // int逸出判斷 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 = a; head = 0; tail = n; }
下面是一個數組擴容的邏輯示意圖索引
1 -> 9 -> 5 -> 7 -> 4 -> 3 -> 5 -> 8
以彈出隊頭的元素爲例,會直接返回隊列頭的元素,並將head前移一位,並將數組中源隊列頭的數據清掉(賦值爲null)接口
public E pollFirst() { int h = head; @SuppressWarnings("unchecked") E result = (E) 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; }
刪除元素的示意圖以下隊列