ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/ArrayDeque.java
Revision: 1.37
Committed: Tue Dec 6 04:37:55 2011 UTC (12 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.36: +10 -5 lines
Log Message:
@SuppressWarnings on its own line of code

File Contents

# Content
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 /**
9 * Resizable-array implementation of the {@link Deque} interface. Array
10 * deques have no capacity restrictions; they grow as necessary to support
11 * usage. They are not thread-safe; in the absence of external
12 * synchronization, they do not support concurrent access by multiple threads.
13 * Null elements are prohibited. This class is likely to be faster than
14 * {@link Stack} when used as a stack, and faster than {@link LinkedList}
15 * when used as a queue.
16 *
17 * <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time.
18 * Exceptions include {@link #remove(Object) remove}, {@link
19 * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence
20 * removeLastOccurrence}, {@link #contains contains}, {@link #iterator
21 * iterator.remove()}, and the bulk operations, all of which run in linear
22 * time.
23 *
24 * <p>The iterators returned by this class's <tt>iterator</tt> method are
25 * <i>fail-fast</i>: If the deque is modified at any time after the iterator
26 * is created, in any way except through the iterator's own <tt>remove</tt>
27 * method, the iterator will generally throw a {@link
28 * ConcurrentModificationException}. Thus, in the face of concurrent
29 * modification, the iterator fails quickly and cleanly, rather than risking
30 * arbitrary, non-deterministic behavior at an undetermined time in the
31 * future.
32 *
33 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
34 * as it is, generally speaking, impossible to make any hard guarantees in the
35 * presence of unsynchronized concurrent modification. Fail-fast iterators
36 * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
37 * Therefore, it would be wrong to write a program that depended on this
38 * exception for its correctness: <i>the fail-fast behavior of iterators
39 * should be used only to detect bugs.</i>
40 *
41 * <p>This class and its iterator implement all of the
42 * <em>optional</em> methods of the {@link Collection} and {@link
43 * Iterator} interfaces.
44 *
45 * <p>This class is a member of the
46 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
47 * Java Collections Framework</a>.
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 */
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 */
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 */
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 */
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 */
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 */
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 */
194 public void addFirst(E e) {
195 if (e == null)
196 throw new NullPointerException();
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 */
210 public void addLast(E e) {
211 if (e == null)
212 throw new NullPointerException();
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 */
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 */
237 public boolean offerLast(E e) {
238 addLast(e);
239 return true;
240 }
241
242 /**
243 * @throws NoSuchElementException {@inheritDoc}
244 */
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 */
255 public E removeLast() {
256 E x = pollLast();
257 if (x == null)
258 throw new NoSuchElementException();
259 return x;
260 }
261
262 public E pollFirst() {
263 int h = head;
264 @SuppressWarnings("unchecked")
265 E result = (E) elements[h];
266 // Element is null if deque empty
267 if (result == null)
268 return null;
269 elements[h] = null; // Must null out slot
270 head = (h + 1) & (elements.length - 1);
271 return result;
272 }
273
274 public E pollLast() {
275 int t = (tail - 1) & (elements.length - 1);
276 @SuppressWarnings("unchecked")
277 E result = (E) elements[t];
278 if (result == null)
279 return null;
280 elements[t] = null;
281 tail = t;
282 return result;
283 }
284
285 /**
286 * @throws NoSuchElementException {@inheritDoc}
287 */
288 public E getFirst() {
289 @SuppressWarnings("unchecked")
290 E result = (E) elements[head];
291 if (result == null)
292 throw new NoSuchElementException();
293 return result;
294 }
295
296 /**
297 * @throws NoSuchElementException {@inheritDoc}
298 */
299 public E getLast() {
300 @SuppressWarnings("unchecked")
301 E result = (E) elements[(tail - 1) & (elements.length - 1)];
302 if (result == null)
303 throw new NoSuchElementException();
304 return result;
305 }
306
307 @SuppressWarnings("unchecked")
308 public E peekFirst() {
309 // elements[head] is null if deque empty
310 return (E) elements[head];
311 }
312
313 @SuppressWarnings("unchecked")
314 public E peekLast() {
315 return (E) elements[(tail - 1) & (elements.length - 1)];
316 }
317
318 /**
319 * Removes the first occurrence of the specified element in this
320 * deque (when traversing the deque from head to tail).
321 * If the deque does not contain the element, it is unchanged.
322 * More formally, removes the first element <tt>e</tt> such that
323 * <tt>o.equals(e)</tt> (if such an element exists).
324 * Returns <tt>true</tt> if this deque contained the specified element
325 * (or equivalently, if this deque changed as a result of the call).
326 *
327 * @param o element to be removed from this deque, if present
328 * @return <tt>true</tt> if the deque contained the specified element
329 */
330 public boolean removeFirstOccurrence(Object o) {
331 if (o == null)
332 return false;
333 int mask = elements.length - 1;
334 int i = head;
335 Object x;
336 while ( (x = elements[i]) != null) {
337 if (o.equals(x)) {
338 delete(i);
339 return true;
340 }
341 i = (i + 1) & mask;
342 }
343 return false;
344 }
345
346 /**
347 * Removes the last occurrence of the specified element in this
348 * deque (when traversing the deque from head to tail).
349 * If the deque does not contain the element, it is unchanged.
350 * More formally, removes the last element <tt>e</tt> such that
351 * <tt>o.equals(e)</tt> (if such an element exists).
352 * Returns <tt>true</tt> if this deque contained the specified element
353 * (or equivalently, if this deque changed as a result of the call).
354 *
355 * @param o element to be removed from this deque, if present
356 * @return <tt>true</tt> if the deque contained the specified element
357 */
358 public boolean removeLastOccurrence(Object o) {
359 if (o == null)
360 return false;
361 int mask = elements.length - 1;
362 int i = (tail - 1) & mask;
363 Object x;
364 while ( (x = elements[i]) != null) {
365 if (o.equals(x)) {
366 delete(i);
367 return true;
368 }
369 i = (i - 1) & mask;
370 }
371 return false;
372 }
373
374 // *** Queue methods ***
375
376 /**
377 * Inserts the specified element at the end of this deque.
378 *
379 * <p>This method is equivalent to {@link #addLast}.
380 *
381 * @param e the element to add
382 * @return <tt>true</tt> (as specified by {@link Collection#add})
383 * @throws NullPointerException if the specified element is null
384 */
385 public boolean add(E e) {
386 addLast(e);
387 return true;
388 }
389
390 /**
391 * Inserts the specified element at the end of this deque.
392 *
393 * <p>This method is equivalent to {@link #offerLast}.
394 *
395 * @param e the element to add
396 * @return <tt>true</tt> (as specified by {@link Queue#offer})
397 * @throws NullPointerException if the specified element is null
398 */
399 public boolean offer(E e) {
400 return offerLast(e);
401 }
402
403 /**
404 * Retrieves and removes the head of the queue represented by this deque.
405 *
406 * This method differs from {@link #poll poll} only in that it throws an
407 * exception if this deque is empty.
408 *
409 * <p>This method is equivalent to {@link #removeFirst}.
410 *
411 * @return the head of the queue represented by this deque
412 * @throws NoSuchElementException {@inheritDoc}
413 */
414 public E remove() {
415 return removeFirst();
416 }
417
418 /**
419 * Retrieves and removes the head of the queue represented by this deque
420 * (in other words, the first element of this deque), or returns
421 * <tt>null</tt> if this deque is empty.
422 *
423 * <p>This method is equivalent to {@link #pollFirst}.
424 *
425 * @return the head of the queue represented by this deque, or
426 * <tt>null</tt> if this deque is empty
427 */
428 public E poll() {
429 return pollFirst();
430 }
431
432 /**
433 * Retrieves, but does not remove, the head of the queue represented by
434 * this deque. This method differs from {@link #peek peek} only in
435 * that it throws an exception if this deque is empty.
436 *
437 * <p>This method is equivalent to {@link #getFirst}.
438 *
439 * @return the head of the queue represented by this deque
440 * @throws NoSuchElementException {@inheritDoc}
441 */
442 public E element() {
443 return getFirst();
444 }
445
446 /**
447 * Retrieves, but does not remove, the head of the queue represented by
448 * this deque, or returns <tt>null</tt> if this deque is empty.
449 *
450 * <p>This method is equivalent to {@link #peekFirst}.
451 *
452 * @return the head of the queue represented by this deque, or
453 * <tt>null</tt> if this deque is empty
454 */
455 public E peek() {
456 return peekFirst();
457 }
458
459 // *** Stack methods ***
460
461 /**
462 * Pushes an element onto the stack represented by this deque. In other
463 * words, inserts the element at the front of this deque.
464 *
465 * <p>This method is equivalent to {@link #addFirst}.
466 *
467 * @param e the element to push
468 * @throws NullPointerException if the specified element is null
469 */
470 public void push(E e) {
471 addFirst(e);
472 }
473
474 /**
475 * Pops an element from the stack represented by this deque. In other
476 * words, removes and returns the first element of this deque.
477 *
478 * <p>This method is equivalent to {@link #removeFirst()}.
479 *
480 * @return the element at the front of this deque (which is the top
481 * of the stack represented by this deque)
482 * @throws NoSuchElementException {@inheritDoc}
483 */
484 public E pop() {
485 return removeFirst();
486 }
487
488 private void checkInvariants() {
489 assert elements[tail] == null;
490 assert head == tail ? elements[head] == null :
491 (elements[head] != null &&
492 elements[(tail - 1) & (elements.length - 1)] != null);
493 assert elements[(head - 1) & (elements.length - 1)] == null;
494 }
495
496 /**
497 * Removes the element at the specified position in the elements array,
498 * adjusting head and tail as necessary. This can result in motion of
499 * elements backwards or forwards in the array.
500 *
501 * <p>This method is called delete rather than remove to emphasize
502 * that its semantics differ from those of {@link List#remove(int)}.
503 *
504 * @return true if elements moved backwards
505 */
506 private boolean delete(int i) {
507 checkInvariants();
508 final Object[] elements = this.elements;
509 final int mask = elements.length - 1;
510 final int h = head;
511 final int t = tail;
512 final int front = (i - h) & mask;
513 final int back = (t - i) & mask;
514
515 // Invariant: head <= i < tail mod circularity
516 if (front >= ((t - h) & mask))
517 throw new ConcurrentModificationException();
518
519 // Optimize for least element motion
520 if (front < back) {
521 if (h <= i) {
522 System.arraycopy(elements, h, elements, h + 1, front);
523 } else { // Wrap around
524 System.arraycopy(elements, 0, elements, 1, i);
525 elements[0] = elements[mask];
526 System.arraycopy(elements, h, elements, h + 1, mask - h);
527 }
528 elements[h] = null;
529 head = (h + 1) & mask;
530 return false;
531 } else {
532 if (i < t) { // Copy the null tail as well
533 System.arraycopy(elements, i + 1, elements, i, back);
534 tail = t - 1;
535 } else { // Wrap around
536 System.arraycopy(elements, i + 1, elements, i, mask - i);
537 elements[mask] = elements[0];
538 System.arraycopy(elements, 1, elements, 0, t);
539 tail = (t - 1) & mask;
540 }
541 return true;
542 }
543 }
544
545 // *** Collection Methods ***
546
547 /**
548 * Returns the number of elements in this deque.
549 *
550 * @return the number of elements in this deque
551 */
552 public int size() {
553 return (tail - head) & (elements.length - 1);
554 }
555
556 /**
557 * Returns <tt>true</tt> if this deque contains no elements.
558 *
559 * @return <tt>true</tt> if this deque contains no elements
560 */
561 public boolean isEmpty() {
562 return head == tail;
563 }
564
565 /**
566 * Returns an iterator over the elements in this deque. The elements
567 * will be ordered from first (head) to last (tail). This is the same
568 * order that elements would be dequeued (via successive calls to
569 * {@link #remove} or popped (via successive calls to {@link #pop}).
570 *
571 * @return an iterator over the elements in this deque
572 */
573 public Iterator<E> iterator() {
574 return new DeqIterator();
575 }
576
577 public Iterator<E> descendingIterator() {
578 return new DescendingIterator();
579 }
580
581 private class DeqIterator implements Iterator<E> {
582 /**
583 * Index of element to be returned by subsequent call to next.
584 */
585 private int cursor = head;
586
587 /**
588 * Tail recorded at construction (also in remove), to stop
589 * iterator and also to check for comodification.
590 */
591 private int fence = tail;
592
593 /**
594 * Index of element returned by most recent call to next.
595 * Reset to -1 if element is deleted by a call to remove.
596 */
597 private int lastRet = -1;
598
599 public boolean hasNext() {
600 return cursor != fence;
601 }
602
603 public E next() {
604 if (cursor == fence)
605 throw new NoSuchElementException();
606 @SuppressWarnings("unchecked")
607 E result = (E) elements[cursor];
608 // This check doesn't catch all possible comodifications,
609 // but does catch the ones that corrupt traversal
610 if (tail != fence || result == null)
611 throw new ConcurrentModificationException();
612 lastRet = cursor;
613 cursor = (cursor + 1) & (elements.length - 1);
614 return result;
615 }
616
617 public void remove() {
618 if (lastRet < 0)
619 throw new IllegalStateException();
620 if (delete(lastRet)) { // if left-shifted, undo increment in next()
621 cursor = (cursor - 1) & (elements.length - 1);
622 fence = tail;
623 }
624 lastRet = -1;
625 }
626 }
627
628 private class DescendingIterator implements Iterator<E> {
629 /*
630 * This class is nearly a mirror-image of DeqIterator, using
631 * tail instead of head for initial cursor, and head instead of
632 * tail for fence.
633 */
634 private int cursor = tail;
635 private int fence = head;
636 private int lastRet = -1;
637
638 public boolean hasNext() {
639 return cursor != fence;
640 }
641
642 public E next() {
643 if (cursor == fence)
644 throw new NoSuchElementException();
645 cursor = (cursor - 1) & (elements.length - 1);
646 @SuppressWarnings("unchecked")
647 E result = (E) elements[cursor];
648 if (head != fence || result == null)
649 throw new ConcurrentModificationException();
650 lastRet = cursor;
651 return result;
652 }
653
654 public void remove() {
655 if (lastRet < 0)
656 throw new IllegalStateException();
657 if (!delete(lastRet)) {
658 cursor = (cursor + 1) & (elements.length - 1);
659 fence = head;
660 }
661 lastRet = -1;
662 }
663 }
664
665 /**
666 * Returns <tt>true</tt> if this deque contains the specified element.
667 * More formally, returns <tt>true</tt> if and only if this deque contains
668 * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
669 *
670 * @param o object to be checked for containment in this deque
671 * @return <tt>true</tt> if this deque contains the specified element
672 */
673 public boolean contains(Object o) {
674 if (o == null)
675 return false;
676 int mask = elements.length - 1;
677 int i = head;
678 Object x;
679 while ( (x = elements[i]) != null) {
680 if (o.equals(x))
681 return true;
682 i = (i + 1) & mask;
683 }
684 return false;
685 }
686
687 /**
688 * Removes a single instance of the specified element from this deque.
689 * If the deque does not contain the element, it is unchanged.
690 * More formally, removes the first element <tt>e</tt> such that
691 * <tt>o.equals(e)</tt> (if such an element exists).
692 * Returns <tt>true</tt> if this deque contained the specified element
693 * (or equivalently, if this deque changed as a result of the call).
694 *
695 * <p>This method is equivalent to {@link #removeFirstOccurrence}.
696 *
697 * @param o element to be removed from this deque, if present
698 * @return <tt>true</tt> if this deque contained the specified element
699 */
700 public boolean remove(Object o) {
701 return removeFirstOccurrence(o);
702 }
703
704 /**
705 * Removes all of the elements from this deque.
706 * The deque will be empty after this call returns.
707 */
708 public void clear() {
709 int h = head;
710 int t = tail;
711 if (h != t) { // clear all cells
712 head = tail = 0;
713 int i = h;
714 int mask = elements.length - 1;
715 do {
716 elements[i] = null;
717 i = (i + 1) & mask;
718 } while (i != t);
719 }
720 }
721
722 /**
723 * Returns an array containing all of the elements in this deque
724 * in proper sequence (from first to last element).
725 *
726 * <p>The returned array will be "safe" in that no references to it are
727 * maintained by this deque. (In other words, this method must allocate
728 * a new array). The caller is thus free to modify the returned array.
729 *
730 * <p>This method acts as bridge between array-based and collection-based
731 * APIs.
732 *
733 * @return an array containing all of the elements in this deque
734 */
735 public Object[] toArray() {
736 return copyElements(new Object[size()]);
737 }
738
739 /**
740 * Returns an array containing all of the elements in this deque in
741 * proper sequence (from first to last element); the runtime type of the
742 * returned array is that of the specified array. If the deque fits in
743 * the specified array, it is returned therein. Otherwise, a new array
744 * is allocated with the runtime type of the specified array and the
745 * size of this deque.
746 *
747 * <p>If this deque fits in the specified array with room to spare
748 * (i.e., the array has more elements than this deque), the element in
749 * the array immediately following the end of the deque is set to
750 * <tt>null</tt>.
751 *
752 * <p>Like the {@link #toArray()} method, this method acts as bridge between
753 * array-based and collection-based APIs. Further, this method allows
754 * precise control over the runtime type of the output array, and may,
755 * under certain circumstances, be used to save allocation costs.
756 *
757 * <p>Suppose <tt>x</tt> is a deque known to contain only strings.
758 * The following code can be used to dump the deque into a newly
759 * allocated array of <tt>String</tt>:
760 *
761 * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
762 *
763 * Note that <tt>toArray(new Object[0])</tt> is identical in function to
764 * <tt>toArray()</tt>.
765 *
766 * @param a the array into which the elements of the deque are to
767 * be stored, if it is big enough; otherwise, a new array of the
768 * same runtime type is allocated for this purpose
769 * @return an array containing all of the elements in this deque
770 * @throws ArrayStoreException if the runtime type of the specified array
771 * is not a supertype of the runtime type of every element in
772 * this deque
773 * @throws NullPointerException if the specified array is null
774 */
775 @SuppressWarnings("unchecked")
776 public <T> T[] toArray(T[] a) {
777 int size = size();
778 if (a.length < size)
779 a = (T[])java.lang.reflect.Array.newInstance(
780 a.getClass().getComponentType(), size);
781 copyElements(a);
782 if (a.length > size)
783 a[size] = null;
784 return a;
785 }
786
787 // *** Object methods ***
788
789 /**
790 * Returns a copy of this deque.
791 *
792 * @return a copy of this deque
793 */
794 public ArrayDeque<E> clone() {
795 try {
796 @SuppressWarnings("unchecked")
797 ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
798 result.elements = Arrays.copyOf(elements, elements.length);
799 return result;
800 } catch (CloneNotSupportedException e) {
801 throw new AssertionError();
802 }
803 }
804
805 /**
806 * Appease the serialization gods.
807 */
808 private static final long serialVersionUID = 2340985798034038923L;
809
810 /**
811 * Serialize this deque.
812 *
813 * @serialData The current size (<tt>int</tt>) of the deque,
814 * followed by all of its elements (each an object reference) in
815 * first-to-last order.
816 */
817 private void writeObject(java.io.ObjectOutputStream s)
818 throws java.io.IOException {
819 s.defaultWriteObject();
820
821 // Write out size
822 s.writeInt(size());
823
824 // Write out elements in order.
825 int mask = elements.length - 1;
826 for (int i = head; i != tail; i = (i + 1) & mask)
827 s.writeObject(elements[i]);
828 }
829
830 /**
831 * Deserialize this deque.
832 */
833 private void readObject(java.io.ObjectInputStream s)
834 throws java.io.IOException, ClassNotFoundException {
835 s.defaultReadObject();
836
837 // Read in size and allocate array
838 int size = s.readInt();
839 allocateElements(size);
840 head = 0;
841 tail = size;
842
843 // Read in all elements in the proper order.
844 for (int i = 0; i < size; i++)
845 elements[i] = s.readObject();
846 }
847 }