• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Written by Josh Bloch of Google Inc. and released to the public domain,
3  * as explained at http://creativecommons.org/publicdomain/zero/1.0/.
4  */
5 
6 package java.util;
7 
8 // BEGIN android-note
9 // removed link to collections framework docs
10 // END android-note
11 
12 /**
13  * Resizable-array implementation of the {@link Deque} interface.  Array
14  * deques have no capacity restrictions; they grow as necessary to support
15  * usage.  They are not thread-safe; in the absence of external
16  * synchronization, they do not support concurrent access by multiple threads.
17  * Null elements are prohibited.  This class is likely to be faster than
18  * {@link Stack} when used as a stack, and faster than {@link LinkedList}
19  * when used as a queue.
20  *
21  * <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time.
22  * Exceptions include {@link #remove(Object) remove}, {@link
23  * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence
24  * removeLastOccurrence}, {@link #contains contains}, {@link #iterator
25  * iterator.remove()}, and the bulk operations, all of which run in linear
26  * time.
27  *
28  * <p>The iterators returned by this class's <tt>iterator</tt> method are
29  * <i>fail-fast</i>: If the deque is modified at any time after the iterator
30  * is created, in any way except through the iterator's own <tt>remove</tt>
31  * method, the iterator will generally throw a {@link
32  * ConcurrentModificationException}.  Thus, in the face of concurrent
33  * modification, the iterator fails quickly and cleanly, rather than risking
34  * arbitrary, non-deterministic behavior at an undetermined time in the
35  * future.
36  *
37  * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
38  * as it is, generally speaking, impossible to make any hard guarantees in the
39  * presence of unsynchronized concurrent modification.  Fail-fast iterators
40  * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
41  * Therefore, it would be wrong to write a program that depended on this
42  * exception for its correctness: <i>the fail-fast behavior of iterators
43  * should be used only to detect bugs.</i>
44  *
45  * <p>This class and its iterator implement all of the
46  * <em>optional</em> methods of the {@link Collection} and {@link
47  * Iterator} interfaces.
48  *
49  * @author  Josh Bloch and Doug Lea
50  * @since   1.6
51  * @param <E> the type of elements held in this collection
52  */
53 public class ArrayDeque<E> extends AbstractCollection<E>
54                            implements Deque<E>, Cloneable, java.io.Serializable
55 {
56     /**
57      * The array in which the elements of the deque are stored.
58      * The capacity of the deque is the length of this array, which is
59      * always a power of two. The array is never allowed to become
60      * full, except transiently within an addX method where it is
61      * resized (see doubleCapacity) immediately upon becoming full,
62      * thus avoiding head and tail wrapping around to equal each
63      * other.  We also guarantee that all array cells not holding
64      * deque elements are always null.
65      */
66     private transient Object[] elements;
67 
68     /**
69      * The index of the element at the head of the deque (which is the
70      * element that would be removed by remove() or pop()); or an
71      * arbitrary number equal to tail if the deque is empty.
72      */
73     private transient int head;
74 
75     /**
76      * The index at which the next element would be added to the tail
77      * of the deque (via addLast(E), add(E), or push(E)).
78      */
79     private transient int tail;
80 
81     /**
82      * The minimum capacity that we'll use for a newly created deque.
83      * Must be a power of 2.
84      */
85     private static final int MIN_INITIAL_CAPACITY = 8;
86 
87     // ******  Array allocation and resizing utilities ******
88 
89     /**
90      * Allocate empty array to hold the given number of elements.
91      *
92      * @param numElements  the number of elements to hold
93      */
allocateElements(int numElements)94     private void allocateElements(int numElements) {
95         int initialCapacity = MIN_INITIAL_CAPACITY;
96         // Find the best power of two to hold elements.
97         // Tests "<=" because arrays aren't kept full.
98         if (numElements >= initialCapacity) {
99             initialCapacity = numElements;
100             initialCapacity |= (initialCapacity >>>  1);
101             initialCapacity |= (initialCapacity >>>  2);
102             initialCapacity |= (initialCapacity >>>  4);
103             initialCapacity |= (initialCapacity >>>  8);
104             initialCapacity |= (initialCapacity >>> 16);
105             initialCapacity++;
106 
107             if (initialCapacity < 0)   // Too many elements, must back off
108                 initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
109         }
110         elements = new Object[initialCapacity];
111     }
112 
113     /**
114      * Double the capacity of this deque.  Call only when full, i.e.,
115      * when head and tail have wrapped around to become equal.
116      */
doubleCapacity()117     private void doubleCapacity() {
118         // assert head == tail;
119         int p = head;
120         int n = elements.length;
121         int r = n - p; // number of elements to the right of p
122         int newCapacity = n << 1;
123         if (newCapacity < 0)
124             throw new IllegalStateException("Sorry, deque too big");
125         Object[] a = new Object[newCapacity];
126         System.arraycopy(elements, p, a, 0, r);
127         System.arraycopy(elements, 0, a, r, p);
128         elements = a;
129         head = 0;
130         tail = n;
131     }
132 
133     /**
134      * Copies the elements from our element array into the specified array,
135      * in order (from first to last element in the deque).  It is assumed
136      * that the array is large enough to hold all elements in the deque.
137      *
138      * @return its argument
139      */
copyElements(T[] a)140     private <T> T[] copyElements(T[] a) {
141         if (head < tail) {
142             System.arraycopy(elements, head, a, 0, size());
143         } else if (head > tail) {
144             int headPortionLen = elements.length - head;
145             System.arraycopy(elements, head, a, 0, headPortionLen);
146             System.arraycopy(elements, 0, a, headPortionLen, tail);
147         }
148         return a;
149     }
150 
151     /**
152      * Constructs an empty array deque with an initial capacity
153      * sufficient to hold 16 elements.
154      */
ArrayDeque()155     public ArrayDeque() {
156         elements = new Object[16];
157     }
158 
159     /**
160      * Constructs an empty array deque with an initial capacity
161      * sufficient to hold the specified number of elements.
162      *
163      * @param numElements  lower bound on initial capacity of the deque
164      */
ArrayDeque(int numElements)165     public ArrayDeque(int numElements) {
166         allocateElements(numElements);
167     }
168 
169     /**
170      * Constructs a deque containing the elements of the specified
171      * collection, in the order they are returned by the collection's
172      * iterator.  (The first element returned by the collection's
173      * iterator becomes the first element, or <i>front</i> of the
174      * deque.)
175      *
176      * @param c the collection whose elements are to be placed into the deque
177      * @throws NullPointerException if the specified collection is null
178      */
ArrayDeque(Collection<? extends E> c)179     public ArrayDeque(Collection<? extends E> c) {
180         allocateElements(c.size());
181         addAll(c);
182     }
183 
184     // The main insertion and extraction methods are addFirst,
185     // addLast, pollFirst, pollLast. The other methods are defined in
186     // terms of these.
187 
188     /**
189      * Inserts the specified element at the front of this deque.
190      *
191      * @param e the element to add
192      * @throws NullPointerException if the specified element is null
193      */
addFirst(E e)194     public void addFirst(E e) {
195         if (e == null)
196             throw new NullPointerException("e == null");
197         elements[head = (head - 1) & (elements.length - 1)] = e;
198         if (head == tail)
199             doubleCapacity();
200     }
201 
202     /**
203      * Inserts the specified element at the end of this deque.
204      *
205      * <p>This method is equivalent to {@link #add}.
206      *
207      * @param e the element to add
208      * @throws NullPointerException if the specified element is null
209      */
addLast(E e)210     public void addLast(E e) {
211         if (e == null)
212             throw new NullPointerException("e == null");
213         elements[tail] = e;
214         if ( (tail = (tail + 1) & (elements.length - 1)) == head)
215             doubleCapacity();
216     }
217 
218     /**
219      * Inserts the specified element at the front of this deque.
220      *
221      * @param e the element to add
222      * @return <tt>true</tt> (as specified by {@link Deque#offerFirst})
223      * @throws NullPointerException if the specified element is null
224      */
offerFirst(E e)225     public boolean offerFirst(E e) {
226         addFirst(e);
227         return true;
228     }
229 
230     /**
231      * Inserts the specified element at the end of this deque.
232      *
233      * @param e the element to add
234      * @return <tt>true</tt> (as specified by {@link Deque#offerLast})
235      * @throws NullPointerException if the specified element is null
236      */
offerLast(E e)237     public boolean offerLast(E e) {
238         addLast(e);
239         return true;
240     }
241 
242     /**
243      * @throws NoSuchElementException {@inheritDoc}
244      */
removeFirst()245     public E removeFirst() {
246         E x = pollFirst();
247         if (x == null)
248             throw new NoSuchElementException();
249         return x;
250     }
251 
252     /**
253      * @throws NoSuchElementException {@inheritDoc}
254      */
removeLast()255     public E removeLast() {
256         E x = pollLast();
257         if (x == null)
258             throw new NoSuchElementException();
259         return x;
260     }
261 
pollFirst()262     public E pollFirst() {
263         int h = head;
264         @SuppressWarnings("unchecked") E result = (E) elements[h];
265         // Element is null if deque empty
266         if (result == null)
267             return null;
268         elements[h] = null;     // Must null out slot
269         head = (h + 1) & (elements.length - 1);
270         return result;
271     }
272 
pollLast()273     public E pollLast() {
274         int t = (tail - 1) & (elements.length - 1);
275         @SuppressWarnings("unchecked") E result = (E) elements[t];
276         if (result == null)
277             return null;
278         elements[t] = null;
279         tail = t;
280         return result;
281     }
282 
283     /**
284      * @throws NoSuchElementException {@inheritDoc}
285      */
getFirst()286     public E getFirst() {
287         @SuppressWarnings("unchecked") E result = (E) elements[head];
288         if (result == null)
289             throw new NoSuchElementException();
290         return result;
291     }
292 
293     /**
294      * @throws NoSuchElementException {@inheritDoc}
295      */
getLast()296     public E getLast() {
297         @SuppressWarnings("unchecked")
298         E result = (E) elements[(tail - 1) & (elements.length - 1)];
299         if (result == null)
300             throw new NoSuchElementException();
301         return result;
302     }
303 
peekFirst()304     public E peekFirst() {
305         @SuppressWarnings("unchecked") E result = (E) elements[head];
306         // elements[head] is null if deque empty
307         return result;
308     }
309 
peekLast()310     public E peekLast() {
311         @SuppressWarnings("unchecked")
312         E result = (E) elements[(tail - 1) & (elements.length - 1)];
313         return result;
314     }
315 
316     /**
317      * Removes the first occurrence of the specified element in this
318      * deque (when traversing the deque from head to tail).
319      * If the deque does not contain the element, it is unchanged.
320      * More formally, removes the first element <tt>e</tt> such that
321      * <tt>o.equals(e)</tt> (if such an element exists).
322      * Returns <tt>true</tt> if this deque contained the specified element
323      * (or equivalently, if this deque changed as a result of the call).
324      *
325      * @param o element to be removed from this deque, if present
326      * @return <tt>true</tt> if the deque contained the specified element
327      */
removeFirstOccurrence(Object o)328     public boolean removeFirstOccurrence(Object o) {
329         if (o == null)
330             return false;
331         int mask = elements.length - 1;
332         int i = head;
333         Object x;
334         while ( (x = elements[i]) != null) {
335             if (o.equals(x)) {
336                 delete(i);
337                 return true;
338             }
339             i = (i + 1) & mask;
340         }
341         return false;
342     }
343 
344     /**
345      * Removes the last occurrence of the specified element in this
346      * deque (when traversing the deque from head to tail).
347      * If the deque does not contain the element, it is unchanged.
348      * More formally, removes the last element <tt>e</tt> such that
349      * <tt>o.equals(e)</tt> (if such an element exists).
350      * Returns <tt>true</tt> if this deque contained the specified element
351      * (or equivalently, if this deque changed as a result of the call).
352      *
353      * @param o element to be removed from this deque, if present
354      * @return <tt>true</tt> if the deque contained the specified element
355      */
removeLastOccurrence(Object o)356     public boolean removeLastOccurrence(Object o) {
357         if (o == null)
358             return false;
359         int mask = elements.length - 1;
360         int i = (tail - 1) & mask;
361         Object x;
362         while ( (x = elements[i]) != null) {
363             if (o.equals(x)) {
364                 delete(i);
365                 return true;
366             }
367             i = (i - 1) & mask;
368         }
369         return false;
370     }
371 
372     // *** Queue methods ***
373 
374     /**
375      * Inserts the specified element at the end of this deque.
376      *
377      * <p>This method is equivalent to {@link #addLast}.
378      *
379      * @param e the element to add
380      * @return <tt>true</tt> (as specified by {@link Collection#add})
381      * @throws NullPointerException if the specified element is null
382      */
add(E e)383     public boolean add(E e) {
384         addLast(e);
385         return true;
386     }
387 
388     /**
389      * Inserts the specified element at the end of this deque.
390      *
391      * <p>This method is equivalent to {@link #offerLast}.
392      *
393      * @param e the element to add
394      * @return <tt>true</tt> (as specified by {@link Queue#offer})
395      * @throws NullPointerException if the specified element is null
396      */
offer(E e)397     public boolean offer(E e) {
398         return offerLast(e);
399     }
400 
401     /**
402      * Retrieves and removes the head of the queue represented by this deque.
403      *
404      * This method differs from {@link #poll poll} only in that it throws an
405      * exception if this deque is empty.
406      *
407      * <p>This method is equivalent to {@link #removeFirst}.
408      *
409      * @return the head of the queue represented by this deque
410      * @throws NoSuchElementException {@inheritDoc}
411      */
remove()412     public E remove() {
413         return removeFirst();
414     }
415 
416     /**
417      * Retrieves and removes the head of the queue represented by this deque
418      * (in other words, the first element of this deque), or returns
419      * <tt>null</tt> if this deque is empty.
420      *
421      * <p>This method is equivalent to {@link #pollFirst}.
422      *
423      * @return the head of the queue represented by this deque, or
424      *         <tt>null</tt> if this deque is empty
425      */
poll()426     public E poll() {
427         return pollFirst();
428     }
429 
430     /**
431      * Retrieves, but does not remove, the head of the queue represented by
432      * this deque.  This method differs from {@link #peek peek} only in
433      * that it throws an exception if this deque is empty.
434      *
435      * <p>This method is equivalent to {@link #getFirst}.
436      *
437      * @return the head of the queue represented by this deque
438      * @throws NoSuchElementException {@inheritDoc}
439      */
element()440     public E element() {
441         return getFirst();
442     }
443 
444     /**
445      * Retrieves, but does not remove, the head of the queue represented by
446      * this deque, or returns <tt>null</tt> if this deque is empty.
447      *
448      * <p>This method is equivalent to {@link #peekFirst}.
449      *
450      * @return the head of the queue represented by this deque, or
451      *         <tt>null</tt> if this deque is empty
452      */
peek()453     public E peek() {
454         return peekFirst();
455     }
456 
457     // *** Stack methods ***
458 
459     /**
460      * Pushes an element onto the stack represented by this deque.  In other
461      * words, inserts the element at the front of this deque.
462      *
463      * <p>This method is equivalent to {@link #addFirst}.
464      *
465      * @param e the element to push
466      * @throws NullPointerException if the specified element is null
467      */
push(E e)468     public void push(E e) {
469         addFirst(e);
470     }
471 
472     /**
473      * Pops an element from the stack represented by this deque.  In other
474      * words, removes and returns the first element of this deque.
475      *
476      * <p>This method is equivalent to {@link #removeFirst()}.
477      *
478      * @return the element at the front of this deque (which is the top
479      *         of the stack represented by this deque)
480      * @throws NoSuchElementException {@inheritDoc}
481      */
pop()482     public E pop() {
483         return removeFirst();
484     }
485 
checkInvariants()486     private void checkInvariants() {
487         // assert elements[tail] == null;
488         // assert head == tail ? elements[head] == null :
489         //     (elements[head] != null &&
490         //      elements[(tail - 1) & (elements.length - 1)] != null);
491         // assert elements[(head - 1) & (elements.length - 1)] == null;
492     }
493 
494     /**
495      * Removes the element at the specified position in the elements array,
496      * adjusting head and tail as necessary.  This can result in motion of
497      * elements backwards or forwards in the array.
498      *
499      * <p>This method is called delete rather than remove to emphasize
500      * that its semantics differ from those of {@link List#remove(int)}.
501      *
502      * @return true if elements moved backwards
503      */
delete(int i)504     private boolean delete(int i) {
505         //checkInvariants();
506         final Object[] elements = this.elements;
507         final int mask = elements.length - 1;
508         final int h = head;
509         final int t = tail;
510         final int front = (i - h) & mask;
511         final int back  = (t - i) & mask;
512 
513         // Invariant: head <= i < tail mod circularity
514         if (front >= ((t - h) & mask))
515             throw new ConcurrentModificationException();
516 
517         // Optimize for least element motion
518         if (front < back) {
519             if (h <= i) {
520                 System.arraycopy(elements, h, elements, h + 1, front);
521             } else { // Wrap around
522                 System.arraycopy(elements, 0, elements, 1, i);
523                 elements[0] = elements[mask];
524                 System.arraycopy(elements, h, elements, h + 1, mask - h);
525             }
526             elements[h] = null;
527             head = (h + 1) & mask;
528             return false;
529         } else {
530             if (i < t) { // Copy the null tail as well
531                 System.arraycopy(elements, i + 1, elements, i, back);
532                 tail = t - 1;
533             } else { // Wrap around
534                 System.arraycopy(elements, i + 1, elements, i, mask - i);
535                 elements[mask] = elements[0];
536                 System.arraycopy(elements, 1, elements, 0, t);
537                 tail = (t - 1) & mask;
538             }
539             return true;
540         }
541     }
542 
543     // *** Collection Methods ***
544 
545     /**
546      * Returns the number of elements in this deque.
547      *
548      * @return the number of elements in this deque
549      */
size()550     public int size() {
551         return (tail - head) & (elements.length - 1);
552     }
553 
554     /**
555      * Returns <tt>true</tt> if this deque contains no elements.
556      *
557      * @return <tt>true</tt> if this deque contains no elements
558      */
isEmpty()559     public boolean isEmpty() {
560         return head == tail;
561     }
562 
563     /**
564      * Returns an iterator over the elements in this deque.  The elements
565      * will be ordered from first (head) to last (tail).  This is the same
566      * order that elements would be dequeued (via successive calls to
567      * {@link #remove} or popped (via successive calls to {@link #pop}).
568      *
569      * @return an iterator over the elements in this deque
570      */
iterator()571     public Iterator<E> iterator() {
572         return new DeqIterator();
573     }
574 
descendingIterator()575     public Iterator<E> descendingIterator() {
576         return new DescendingIterator();
577     }
578 
579     private class DeqIterator implements Iterator<E> {
580         /**
581          * Index of element to be returned by subsequent call to next.
582          */
583         private int cursor = head;
584 
585         /**
586          * Tail recorded at construction (also in remove), to stop
587          * iterator and also to check for comodification.
588          */
589         private int fence = tail;
590 
591         /**
592          * Index of element returned by most recent call to next.
593          * Reset to -1 if element is deleted by a call to remove.
594          */
595         private int lastRet = -1;
596 
hasNext()597         public boolean hasNext() {
598             return cursor != fence;
599         }
600 
next()601         public E next() {
602             if (cursor == fence)
603                 throw new NoSuchElementException();
604             @SuppressWarnings("unchecked") E result = (E) elements[cursor];
605             // This check doesn't catch all possible comodifications,
606             // but does catch the ones that corrupt traversal
607             if (tail != fence || result == null)
608                 throw new ConcurrentModificationException();
609             lastRet = cursor;
610             cursor = (cursor + 1) & (elements.length - 1);
611             return result;
612         }
613 
remove()614         public void remove() {
615             if (lastRet < 0)
616                 throw new IllegalStateException();
617             if (delete(lastRet)) { // if left-shifted, undo increment in next()
618                 cursor = (cursor - 1) & (elements.length - 1);
619                 fence = tail;
620             }
621             lastRet = -1;
622         }
623     }
624 
625     private class DescendingIterator implements Iterator<E> {
626         /*
627          * This class is nearly a mirror-image of DeqIterator, using
628          * tail instead of head for initial cursor, and head instead of
629          * tail for fence.
630          */
631         private int cursor = tail;
632         private int fence = head;
633         private int lastRet = -1;
634 
hasNext()635         public boolean hasNext() {
636             return cursor != fence;
637         }
638 
next()639         public E next() {
640             if (cursor == fence)
641                 throw new NoSuchElementException();
642             cursor = (cursor - 1) & (elements.length - 1);
643             @SuppressWarnings("unchecked") E result = (E) elements[cursor];
644             if (head != fence || result == null)
645                 throw new ConcurrentModificationException();
646             lastRet = cursor;
647             return result;
648         }
649 
remove()650         public void remove() {
651             if (lastRet < 0)
652                 throw new IllegalStateException();
653             if (!delete(lastRet)) {
654                 cursor = (cursor + 1) & (elements.length - 1);
655                 fence = head;
656             }
657             lastRet = -1;
658         }
659     }
660 
661     /**
662      * Returns <tt>true</tt> if this deque contains the specified element.
663      * More formally, returns <tt>true</tt> if and only if this deque contains
664      * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
665      *
666      * @param o object to be checked for containment in this deque
667      * @return <tt>true</tt> if this deque contains the specified element
668      */
contains(Object o)669     public boolean contains(Object o) {
670         if (o == null)
671             return false;
672         int mask = elements.length - 1;
673         int i = head;
674         Object x;
675         while ( (x = elements[i]) != null) {
676             if (o.equals(x))
677                 return true;
678             i = (i + 1) & mask;
679         }
680         return false;
681     }
682 
683     /**
684      * Removes a single instance of the specified element from this deque.
685      * If the deque does not contain the element, it is unchanged.
686      * More formally, removes the first element <tt>e</tt> such that
687      * <tt>o.equals(e)</tt> (if such an element exists).
688      * Returns <tt>true</tt> if this deque contained the specified element
689      * (or equivalently, if this deque changed as a result of the call).
690      *
691      * <p>This method is equivalent to {@link #removeFirstOccurrence}.
692      *
693      * @param o element to be removed from this deque, if present
694      * @return <tt>true</tt> if this deque contained the specified element
695      */
remove(Object o)696     public boolean remove(Object o) {
697         return removeFirstOccurrence(o);
698     }
699 
700     /**
701      * Removes all of the elements from this deque.
702      * The deque will be empty after this call returns.
703      */
clear()704     public void clear() {
705         int h = head;
706         int t = tail;
707         if (h != t) { // clear all cells
708             head = tail = 0;
709             int i = h;
710             int mask = elements.length - 1;
711             do {
712                 elements[i] = null;
713                 i = (i + 1) & mask;
714             } while (i != t);
715         }
716     }
717 
718     /**
719      * Returns an array containing all of the elements in this deque
720      * in proper sequence (from first to last element).
721      *
722      * <p>The returned array will be "safe" in that no references to it are
723      * maintained by this deque.  (In other words, this method must allocate
724      * a new array).  The caller is thus free to modify the returned array.
725      *
726      * <p>This method acts as bridge between array-based and collection-based
727      * APIs.
728      *
729      * @return an array containing all of the elements in this deque
730      */
toArray()731     public Object[] toArray() {
732         return copyElements(new Object[size()]);
733     }
734 
735     /**
736      * Returns an array containing all of the elements in this deque in
737      * proper sequence (from first to last element); the runtime type of the
738      * returned array is that of the specified array.  If the deque fits in
739      * the specified array, it is returned therein.  Otherwise, a new array
740      * is allocated with the runtime type of the specified array and the
741      * size of this deque.
742      *
743      * <p>If this deque fits in the specified array with room to spare
744      * (i.e., the array has more elements than this deque), the element in
745      * the array immediately following the end of the deque is set to
746      * <tt>null</tt>.
747      *
748      * <p>Like the {@link #toArray()} method, this method acts as bridge between
749      * array-based and collection-based APIs.  Further, this method allows
750      * precise control over the runtime type of the output array, and may,
751      * under certain circumstances, be used to save allocation costs.
752      *
753      * <p>Suppose <tt>x</tt> is a deque known to contain only strings.
754      * The following code can be used to dump the deque into a newly
755      * allocated array of <tt>String</tt>:
756      *
757      *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
758      *
759      * Note that <tt>toArray(new Object[0])</tt> is identical in function to
760      * <tt>toArray()</tt>.
761      *
762      * @param a the array into which the elements of the deque are to
763      *          be stored, if it is big enough; otherwise, a new array of the
764      *          same runtime type is allocated for this purpose
765      * @return an array containing all of the elements in this deque
766      * @throws ArrayStoreException if the runtime type of the specified array
767      *         is not a supertype of the runtime type of every element in
768      *         this deque
769      * @throws NullPointerException if the specified array is null
770      */
771     @SuppressWarnings("unchecked")
toArray(T[] a)772     public <T> T[] toArray(T[] a) {
773         int size = size();
774         if (a.length < size)
775             a = (T[])java.lang.reflect.Array.newInstance(
776                     a.getClass().getComponentType(), size);
777         copyElements(a);
778         if (a.length > size)
779             a[size] = null;
780         return a;
781     }
782 
783     // *** Object methods ***
784 
785     /**
786      * Returns a copy of this deque.
787      *
788      * @return a copy of this deque
789      */
clone()790     public ArrayDeque<E> clone() {
791         try {
792             @SuppressWarnings("unchecked")
793             ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
794             result.elements = Arrays.copyOf(elements, elements.length);
795             return result;
796 
797         } catch (CloneNotSupportedException e) {
798             throw new AssertionError();
799         }
800     }
801 
802     /**
803      * Appease the serialization gods.
804      */
805     private static final long serialVersionUID = 2340985798034038923L;
806 
807     /**
808      * Serialize this deque.
809      *
810      * @serialData The current size (<tt>int</tt>) of the deque,
811      * followed by all of its elements (each an object reference) in
812      * first-to-last order.
813      */
writeObject(java.io.ObjectOutputStream s)814     private void writeObject(java.io.ObjectOutputStream s)
815             throws java.io.IOException {
816         s.defaultWriteObject();
817 
818         // Write out size
819         s.writeInt(size());
820 
821         // Write out elements in order.
822         int mask = elements.length - 1;
823         for (int i = head; i != tail; i = (i + 1) & mask)
824             s.writeObject(elements[i]);
825     }
826 
827     /**
828      * Deserialize this deque.
829      */
readObject(java.io.ObjectInputStream s)830     private void readObject(java.io.ObjectInputStream s)
831             throws java.io.IOException, ClassNotFoundException {
832         s.defaultReadObject();
833 
834         // Read in size and allocate array
835         int size = s.readInt();
836         allocateElements(size);
837         head = 0;
838         tail = size;
839 
840         // Read in all elements in the proper order.
841         for (int i = 0; i < size; i++)
842             elements[i] = s.readObject();
843     }
844 }
845