ArrayDeque
基于循环数组实现的双端队列
目录
ArrayDeque继承关系
ArrayDeque实现了Serializable接口,支持序列化,可通过序列化传输
ArrayDeque实现了Cloneable接口,覆盖了clone()方法,能被克隆
ArrayDeque实现了Deque接口,可作为双端队列使用
ArrayDeque继承了AbstractCollection抽象类,可以执行集合的基本操作
ArrayDeque源码解析
私有 迭代器类DeqIterator:
private class DeqIterator implements Iterator<E> {
/**
* 后续调用next返回的元素索引
*/
int cursor;
/**
* 尚未返回的元素数量
*/
int remaining = size();
/**
* 最近一次调用next返回的元素索引
* 如果元素通过调用remove删除, 则重置为-1
*/
int lastRet = -1;
DeqIterator() { cursor = head; }
public final boolean hasNext() {
return remaining > 0;
}
public E next() {
if (remaining <= 0)
throw new NoSuchElementException();
final Object[] es = elements;
E e = nonNullElementAt(es, cursor); // 用于索引的元素是否为null
cursor = inc(lastRet = cursor, es.length); // 返回 cursor + 1, 若 cursor + 1 >= length , 则返回 0
remaining--;
return e;
}
void postDelete(boolean leftShifted) {
if (leftShifted)
cursor = dec(cursor, elements.length); // 返回 cursor - 1, 若 cursor - 1 < 0, 则返回 length - 1
}
public final void remove() {
if (lastRet < 0)
throw new IllegalStateException();
postDelete(delete(lastRet)); // 调用ArrayDeque的删除方法, 删除成功后调用 postDelete 使 cursor - 1
lastRet = -1;
}
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
int r;
if ((r = remaining) <= 0)
return;
remaining = 0;
final Object[] es = elements;
// sub() = 若 尾部索引tail - 当前索引cursor < 0 则 tail + length
// sub != 尚未返回的元素数量 则抛出ConcurrentModificationException(集被修改过)
if (es[cursor] == null || sub(tail, cursor, es.length) != r)
throw new ConcurrentModificationException();
for (int i = cursor, end = tail, to = (i <= end) ? end : es.length;
; i = 0, to = end) {
for (; i < to; i++)
action.accept(elementAt(es, i));
if (to == end) {
if (end != tail)
throw new ConcurrentModificationException();
lastRet = dec(end, es.length);
break;
}
}
}
}
私有逆序 迭代器DescendingIterator:
private class DescendingIterator extends DeqIterator {
DescendingIterator() { cursor = dec(tail, elements.length); }
public final E next() {
if (remaining <= 0)
throw new NoSuchElementException();
final Object[] es = elements;
E e = nonNullElementAt(es, cursor);
cursor = dec(lastRet = cursor, es.length); // 返回 cursor - 1, 若 cursor - 1 < 0, 则返回 length - 1
remaining--;
return e;
}
void postDelete(boolean leftShifted) {
if (!leftShifted)
cursor = inc(cursor, elements.length); // 返回 cursor + 1, 若 cursor + 1 >= length , 则返回 0
}
public final void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
int r;
if ((r = remaining) <= 0)
return;
remaining = 0;
final Object[] es = elements;
// sub() = 若 当前索引cursor - 头部索引hed < 0 则 cursor + length
// sub != 尚未返回的元素数量 则抛出ConcurrentModificationException(集被修改过)
if (es[cursor] == null || sub(cursor, head, es.length) + 1 != r)
throw new ConcurrentModificationException();
for (int i = cursor, end = head, to = (i >= end) ? end : 0;
; i = es.length - 1, to = end) {
// hotspot generates faster code than for: i >= to !
for (; i > to - 1; i--)
action.accept(elementAt(es, i));
if (to == end) {
if (end != head)
throw new ConcurrentModificationException();
lastRet = end;
break;
}
}
}
}
私有 可分割迭代器类DeqSpliterator:
final class DeqSpliterator implements Spliterator<E> {
private int fence; // -1 until first use
private int cursor; // current index, modified on traverse/split
/** Constructs late-binding spliterator over all elements. */
DeqSpliterator() {
this.fence = -1;
}
/** Constructs spliterator over the given range. */
DeqSpliterator(int origin, int fence) {
// assert 0 <= origin && origin < elements.length;
// assert 0 <= fence && fence < elements.length;
this.cursor = origin;
this.fence = fence;
}
/** Ensures late-binding initialization; then returns fence. */
private int getFence() { // force initialization
int t;
if ((t = fence) < 0) {
t = fence = tail;
cursor = head;
}
return t;
}
public DeqSpliterator trySplit() {
final Object[] es = elements;
final int i, n;
return ((n = sub(getFence(), i = cursor, es.length) >> 1) <= 0)
? null
: new DeqSpliterator(i, cursor = inc(i, n, es.length));
}
public void forEachRemaining(Consumer<? super E> action) {
if (action == null)
throw new NullPointerException();
final int end = getFence(), cursor = this.cursor;
final Object[] es = elements;
if (cursor != end) {
this.cursor = end;
// null check at both ends of range is sufficient
if (es[cursor] == null || es[dec(end, es.length)] == null)
throw new ConcurrentModificationException();
for (int i = cursor, to = (i <= end) ? end : es.length;
; i = 0, to = end) {
for (; i < to; i++)
action.accept(elementAt(es, i));
if (to == end) break;
}
}
}
public boolean tryAdvance(Consumer<? super E> action) {
Objects.requireNonNull(action);
final Object[] es = elements;
if (fence < 0) { fence = tail; cursor = head; } // late-binding
final int i;
if ((i = cursor) == fence)
return false;
E e = nonNullElementAt(es, i);
cursor = inc(i, es.length);
action.accept(e);
return true;
}
public long estimateSize() {
return sub(getFence(), cursor, elements.length);
}
public int characteristics() {
return Spliterator.NONNULL| Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
}
}
ArrayDeque构造方法:
/**
*
* 创建一个初始容量=16的空双端队列
*/
public ArrayDeque() {
elements = new Object[16];
}
/**
* 创建一个指定容量的空双端队列
*
* @param numElements lower bound on initial capacity of the deque
*/
public ArrayDeque(int numElements) {
elements =
new Object[(numElements < 1) ? 1 :
(numElements == Integer.MAX_VALUE) ? Integer.MAX_VALUE :
numElements + 1];
}
/**
* 创建一个包含指定集合的双端队列, 队列顺序按照迭代器顺序
*
* @param c the collection whose elements are to be placed into the deque
* @throws NullPointerException if the specified collection is null
*/
public ArrayDeque(Collection<? extends E> c) {
this(c.size());
copyElements(c);
}
ArrayDeque索引操作:
/**
* 循环 +i
* 0 <= i < modulus
*/
static final int inc(int i, int modulus) {
if (++i >= modulus) i = 0;
return i;
}
/**
* 循环 -i
* 0 <= i < modulus
*/
static final int dec(int i, int modulus) {
if (--i < 0) i = modulus - 1;
return i;
}
/**
* 将给定距离循环添加到索引i
* 0 <= i < modulus , 0 <= distance <= modulus
*
* @return index 0 <= i < modulus
*/
static final int inc(int i, int distance, int modulus) {
if ((i += distance) - modulus >= 0) i -= modulus;
return i;
}
/**
* i = i - j, i < j
* 前提:0 <= i < modulus, 0 <= j < modulus
* @return the "circular distance" from j to i; corner case i == j
* is disambiguated to "empty", returning 0.
*/
static final int sub(int i, int j, int modulus) {
if ((i -= j) < 0) i += modulus;
return i;
}
ArrayDeque主要增删查方法:
// 主要的插入和提取方法是addFirst, addLast, pollFirst, pollLast
// 其他方法是根据这些定义的
/**
* 将指定元素插入到双端队列的头部
*
* @param e the element to add
* @throws NullPointerException if the specified element is null
*/
public void addFirst(E e) {
if (e == null)
throw new NullPointerException();
final Object[] es = elements;
es[head = dec(head, es.length)] = e; // --head, 若 --head < 0 则 head = length - 1
if (head == tail)
grow(1); // 数组已满, 添加位置
}
/**
* 将指定元素插入到双端队列的末尾
*
* <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();
final Object[] es = elements;
es[tail] = e;
if (head == (tail = inc(tail, es.length))) // ++tail, 若 ++tail >= length 则 tail= 0
grow(1);
}
/**
* 在队列末尾添加指定集合中所有元素
* 与对每个元素调用addLast相同
*
* @param c the elements to be inserted into this deque
* @return {@code true} if this deque changed as a result of the call
* @throws NullPointerException if the specified collection or any
* of its elements are null
*/
public boolean addAll(Collection<? extends E> c) {
final int s, needed;
// needed 队列需增加的容量, s + c.size() = 队列所需容量, elements.length 目前队列容量
if ((needed = (s = size()) + c.size() + 1 - elements.length) > 0)
grow(needed);
copyElements(c); // 循环调用addLast
return size() > s;
}
/**
* 对集合元素循环调用addLast方法
*/
private void copyElements(Collection<? extends E> c) {
c.forEach(this::addLast);
}
/**
* 指定元素插入队列头部
*
* @param e the element to add
* @return {@code true} (as specified by {@link Deque#offerFirst})
* @throws NullPointerException if the specified element is null
*/
public boolean offerFirst(E e) {
addFirst(e);
return true;
}
/**
* 指定元素插入队列末尾
*
* @param e the element to add
* @return {@code true} (as specified by {@link Deque#offerLast})
* @throws NullPointerException if the specified element is null
*/
public boolean offerLast(E e) {
addLast(e);
return true;
}
/**
* 移除队列头部元素并返回
* @throws NoSuchElementException {@inheritDoc}
*/
public E removeFirst() {
E e = pollFirst();
if (e == null)
throw new NoSuchElementException();
return e;
}
/**
* 移除队列末尾元素并返回
* @throws NoSuchElementException {@inheritDoc}
*/
public E removeLast() {
E e = pollLast();
if (e == null)
throw new NoSuchElementException();
return e;
}
/**
* 抛出头部元素
*/
public E pollFirst() {
final Object[] es;
final int h;
E e = elementAt(es = elements, h = head);
if (e != null) {
es[h] = null;
head = inc(h, es.length);
}
return e;
}
/**
* 抛出尾部元素
*/
public E pollLast() {
final Object[] es;
final int t;
E e = elementAt(es = elements, t = dec(tail, es.length)); // --tail, 若 --tail < 0 则 tail = length - 1
if (e != null)
es[tail = t] = null;
return e;
}
/**
* @throws NoSuchElementException {@inheritDoc}
*/
public E getFirst() {
E e = elementAt(elements, head);
if (e == null)
throw new NoSuchElementException();
return e;
}
/**
* @throws NoSuchElementException {@inheritDoc}
*/
public E getLast() {
final Object[] es = elements;
E e = elementAt(es, dec(tail, es.length));
if (e == null)
throw new NoSuchElementException();
return e;
}
public E peekFirst() {
return elementAt(elements, head);
}
public E peekLast() {
final Object[] es;
return elementAt(es = elements, dec(tail, es.length));
}
/**
* 从头开始遍历, 若存在一个元素e使得o.equals(e), 则删除元素e, 返回true
*
* @param o element to be removed from this deque, if present
* @return {@code true} if the deque contained the specified element
*/
public boolean removeFirstOccurrence(Object o) {
if (o != null) {
final Object[] es = elements;
for (int i = head, end = tail, to = (i <= end) ? end : es.length;
; i = 0, to = end) {
for (; i < to; i++)
if (o.equals(es[i])) {
delete(i);
return true;
}
if (to == end) break;
}
}
return false;
}
/**
*
* 从末尾开始遍历, 若存在一个元素e使得o.equals(e), 则删除元素e, 返回true
*
* @param o element to be removed from this deque, if present
* @return {@code true} if the deque contained the specified element
*/
public boolean removeLastOccurrence(Object o) {
if (o != null) {
final Object[] es = elements;
for (int i = tail, end = head, to = (i >= end) ? end : 0;
; i = es.length, to = end) {
for (i--; i > to - 1; i--)
if (o.equals(es[i])) {
delete(i);
return true;
}
if (to == end) break;
}
}
return false;
}
/**
* Returns element at array index i.
* This is a slight abuse of generics, accepted by javac.
*/
@SuppressWarnings("unchecked")
static final <E> E elementAt(Object[] es, int i) {
return (E) es[i];
}
/**
* A version of elementAt that checks for null elements.
* This check doesn't catch all possible comodifications,
* but does catch ones that corrupt traversal.
*/
static final <E> E nonNullElementAt(Object[] es, int i) {
@SuppressWarnings("unchecked") E e = (E) es[i];
if (e == null)
throw new ConcurrentModificationException();
return e;
}
/**
* 顺序遍历队列, 若存在元素e使得o.equals(e)
* 则删除元素e
*
* <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}.
*
* @param o element to be removed from this deque, if present
* @return {@code true} if this deque contained the specified element
*/
public boolean remove(Object o) {
return removeFirstOccurrence(o);
}
/**
* 清空队列
*/
public void clear() {
circularClear(elements, head, tail);
head = tail = 0;
}
/**
* 清空数组区间,从 i 到 end
*/
private static void circularClear(Object[] es, int i, int end) {
// assert 0 <= i && i < es.length;
// assert 0 <= end && end < es.length;
for (int to = (i <= end) ? end : es.length;
; i = 0, to = end) {
for (; i < to; i++) es[i] = null;
if (to == end) break;
}
}
/**
* Helper for bulkRemove, in case of at least one deletion.
* Tolerate predicates that reentrantly access the collection for
* read (but writers still get CME), so traverse once to find
* elements to delete, a second pass to physically expunge.
*
* @param beg valid index of first element to be deleted
*/
private boolean bulkRemoveModified(
Predicate<? super E> filter, final int beg) {
final Object[] es = elements;
final int capacity = es.length;
final int end = tail;
final long[] deathRow = nBits(sub(end, beg, capacity));
deathRow[0] = 1L; // set bit 0
for (int i = beg + 1, to = (i <= end) ? end : es.length, k = beg;
; i = 0, to = end, k -= capacity) {
for (; i < to; i++)
if (filter.test(elementAt(es, i)))
setBit(deathRow, i - k);
if (to == end) break;
}
// a two-finger traversal, with hare i reading, tortoise w writing
int w = beg;
for (int i = beg + 1, to = (i <= end) ? end : es.length, k = beg;
; w = 0) { // w rejoins i on second leg
// In this loop, i and w are on the same leg, with i > w
for (; i < to; i++)
if (isClear(deathRow, i - k))
es[w++] = es[i];
if (to == end) break;
// In this loop, w is on the first leg, i on the second
for (i = 0, to = end, k -= capacity; i < to && w < capacity; i++)
if (isClear(deathRow, i - k))
es[w++] = es[i];
if (i >= to) {
if (w == capacity) w = 0; // "corner" case
break;
}
}
if (end != tail) throw new ConcurrentModificationException();
circularClear(es, tail = w, end);
return true;
}
/**
* 删除队列中满足表达式的元素
* @throws NullPointerException {@inheritDoc}
*/
public boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
return bulkRemove(filter); // 批量删除
}
/**
* 从队列中删除所有包含在指定集合中的元素
* @throws NullPointerException {@inheritDoc}
*/
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
return bulkRemove(e -> c.contains(e));
}
/**
* 从队列中删除所有未包含在指定集合中的元素
* @throws NullPointerException {@inheritDoc}
*/
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
return bulkRemove(e -> !c.contains(e));
}
/**
* 批量删除
*/
private boolean bulkRemove(Predicate<? super E> filter) {
final Object[] es = elements;
// Optimize for initial run of survivors
for (int i = head, end = tail, to = (i <= end) ? end : es.length;
; i = 0, to = end) {
for (; i < to; i++)
if (filter.test(elementAt(es, i)))
return bulkRemoveModified(filter, i);
if (to == end) {
if (end != tail) throw new ConcurrentModificationException();
break;
}
}
return false;
}
private static long[] nBits(int n) {
return new long[((n - 1) >> 6) + 1];
}
private static void setBit(long[] bits, int i) {
bits[i >> 6] |= 1L << i;
}
private static boolean isClear(long[] bits, int i) {
return (bits[i >> 6] & (1L << i)) == 0;
}
ArrayDeque队列方法:
// *** Queue methods ***
/**
* 指定元素插入队列尾部
*
* <p>This method is equivalent to {@link #addLast}.
*
* @param e the element to add
* @return {@code true} (as specified by {@link Collection#add})
* @throws NullPointerException if the specified element is null
*/
public boolean add(E e) {
addLast(e);
return true;
}
/**
* 指定元素插入队列尾部
*
* <p>This method is equivalent to {@link #offerLast}.
*
* @param e the element to add
* @return {@code true} (as specified by {@link Queue#offer})
* @throws NullPointerException if the specified element is null
*/
public boolean offer(E e) {
return offerLast(e);
}
/**
* 检索并删除队列的头部元素
* 元素为空则抛出异常NoSuchElementException
*
* <p>This method is equivalent to {@link #removeFirst}.
*
* @return the head of the queue represented by this deque
* @throws NoSuchElementException {@inheritDoc}
*/
public E remove() {
return removeFirst();
}
/**
* 检索并删除队列代表的头部元素
* 元素为空则返回null
*
* <p>This method is equivalent to {@link #pollFirst}.
*
* @return the head of the queue represented by this deque, or
* {@code null} if this deque is empty
*/
public E poll() {
return pollFirst();
}
/**
* 检索但不删除队列的头部元素
* 元素为空则抛出异常NoSuchElementException
*
* <p>This method is equivalent to {@link #getFirst}.
*
* @return the head of the queue represented by this deque
* @throws NoSuchElementException {@inheritDoc}
*/
public E element() {
return getFirst();
}
/**
* 检索但不删除队列的头部元素
* 元素为空则返回null
*
* <p>This method is equivalent to {@link #peekFirst}.
*
* @return the head of the queue represented by this deque, or
* {@code null} if this deque is empty
*/
public E peek() {
return peekFirst();
}
ArrayDeque栈方法:
// *** Stack methods ***
/**
* 将元素插入队列的头部
*
* @param e the element to push
* @throws NullPointerException if the specified element is null
*/
public void push(E e) {
addFirst(e);
}
/**
* 删除并返回此队列的第一个元素
*
* @return the element at the front of this deque (which is the top
* of the stack represented by this deque)
* @throws NoSuchElementException {@inheritDoc}
*/
public E pop() {
return removeFirst();
}
/**
* 删除elements数组中指定位置的元素
*
*
* <p>This method is called delete rather than remove to emphasize
* that its semantics differ from those of {@link List#remove(int)}.
*
* @return true if elements near tail moved backwards
*/
boolean delete(int i) {
final Object[] es = elements;
final int capacity = es.length;
final int h, t;
// number of elements before to-be-deleted elt
final int front = sub(i, h = head, capacity); // i - head < 0 ? i - head + capacity : i - head
// number of elements after to-be-deleted elt
final int back = sub(t = tail, i, capacity) - 1; // tail - i < 0 ? tail - i + capacity - 1 : tail - i - 1
if (front < back) {
// move front elements forwards
if (h <= i) {
System.arraycopy(es, h, es, h + 1, front); // 删除了头部的元素
} else { // Wrap around
System.arraycopy(es, 0, es, 1, i);
es[0] = es[capacity - 1];
System.arraycopy(es, h, es, h + 1, front - (i + 1));
}
es[h] = null;
head = inc(h, capacity);
return false;
} else {
// move back elements backwards
tail = dec(t, capacity);
if (i <= tail) {
System.arraycopy(es, i + 1, es, i, back); // 从i+1开始的back个元素左移一个位置
} else { // Wrap around
System.arraycopy(es, i + 1, es, i, capacity - (i + 1));
es[capacity - 1] = es[0];
System.arraycopy(es, 1, es, 0, t - 1);
}
es[tail] = null;
return true;
}
}
ArrayDeque转换数组操作:
/**
* 返回队列中所有元素的数组
* 双端队列不保留对其的引用, 需分配一个新数组
*
* <p>This method acts as bridge between array-based and collection-based
* APIs.
*
* @return an array containing all of the elements in this deque
*/
public Object[] toArray() {
return toArray(Object[].class);
}
private <T> T[] toArray(Class<T[]> klazz) {
final Object[] es = elements;
final T[] a;
final int head = this.head, tail = this.tail, end;
if ((end = tail + ((head <= tail) ? 0 : es.length)) >= 0) {
// Uses null extension feature of copyOfRange
a = Arrays.copyOfRange(es, head, end, klazz);
} else {
// integer overflow!
a = Arrays.copyOfRange(es, 0, end - head, klazz);
System.arraycopy(es, head, a, 0, es.length - head);
}
if (end != tail)
System.arraycopy(es, 0, a, es.length - head, tail);
return a;
}
/**
* 返回一个包含队列所有元素的数组, 返回类型是指定数组的运行时类型
* 若 队列大小 < 指定数组大小, 则在数组中返回
* 否则将使用指定数组的运行时类型和队列的大小分配一个新数组
*
* 若队列适合指定的数组并有剩余空间, 则多余的位置元素设置为null
*
* 此方法充当基于数组的API和基于集合的API之间的桥梁
* 且允许对输出数组的运行时类型进行精确控制, 并且在某些情况下可以用于节省分配成本
*
* 假设x是已知仅包含字符串的双端队列
* 以下代码可用于将双端队列转储到新分配的String数组中:
* String[] y = x.toArray(new String[0]);
*
* toArray(new Object[0])功能上与toArray()相同
*
* @param a the array into which the elements of the deque are to
* be stored, if it is big enough; otherwise, a new array of the
* same runtime type is allocated for this purpose
* @return an array containing all of the elements in this deque
* @throws ArrayStoreException if the runtime type of the specified array
* is not a supertype of the runtime type of every element in
* this deque
* @throws NullPointerException if the specified array is null
*/
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
final int size;
if ((size = size()) > a.length)
return toArray((Class<T[]>) a.getClass());
final Object[] es = elements;
for (int i = head, j = 0, len = Math.min(size, es.length - i);
; i = 0, len = tail) {
System.arraycopy(es, i, a, j, len);
if ((j += len) == size) break;
}
if (size < a.length)
a[size] = null;
return a;
}
ArrayDeque其他操作:
// *** Collection Methods ***
/**
* Returns the number of elements in this deque.
*
* @return the number of elements in this deque
*/
public int size() {
return sub(tail, head, elements.length);
}
/**
* Returns {@code true} if this deque contains no elements.
*
* @return {@code true} if this deque contains no elements
*/
public boolean isEmpty() {
return head == tail;
}
/**
* Returns an iterator over the elements in this deque. The elements
* will be ordered from first (head) to last (tail). This is the same
* order that elements would be dequeued (via successive calls to
* {@link #remove} or popped (via successive calls to {@link #pop}).
*
* @return an iterator over the elements in this deque
*/
public Iterator<E> iterator() {
return new DeqIterator();
}
/**
* 返回逆序的迭代器
*/
public Iterator<E> descendingIterator() {
return new DescendingIterator();
}
/**
* Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
* and <em>fail-fast</em> {@link Spliterator} over the elements in this
* deque.
*
* <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
* {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
* {@link Spliterator#NONNULL}. Overriding implementations should document
* the reporting of additional characteristic values.
*
* @return a {@code Spliterator} over the elements in this deque
* @since 1.8
*/
public Spliterator<E> spliterator() {
return new DeqSpliterator();
}
/**
* @throws NullPointerException {@inheritDoc}
*/
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
final Object[] es = elements;
for (int i = head, end = tail, to = (i <= end) ? end : es.length;
; i = 0, to = end) {
for (; i < to; i++)
action.accept(elementAt(es, i));
if (to == end) {
if (end != tail) throw new ConcurrentModificationException();
break;
}
}
}
/**
* 至少有一个元素使得o.equals(e)
*
* @param o object to be checked for containment in this deque
* @return {@code true} if this deque contains the specified element
*/
public boolean contains(Object o) {
if (o != null) {
final Object[] es = elements;
for (int i = head, end = tail, to = (i <= end) ? end : es.length;
; i = 0, to = end) {
for (; i < to; i++)
if (o.equals(es[i]))
return true;
if (to == end) break;
}
}
return false;
}
ArrayDeque总结
ArrayDeque即可当作双端队列使用,也可当作栈使用。
ArrayDeque无论是作为队列还是栈使用,性能均高于 LinkedList。
ArrayDeque具有快速失败特征,不能并发修改。
ArrayDeque是线程不安全的,无同步策略。
ArrayDeque不允许插入null元素。