ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk7/java/util/ArrayDeque.java
Revision: 1.1
Committed: Sun Dec 16 20:55:09 2012 UTC (11 years, 5 months ago) by dl
Branch: MAIN
Log Message:
Create src/jdk7 package

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