ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk7/java/util/ArrayDeque.java
Revision: 1.4
Committed: Wed Nov 16 19:56:44 2016 UTC (7 years, 5 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +1 -1 lines
Log Message:
comment out call to checkInvariants

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 * Constructs an empty array deque with an initial capacity
137 * sufficient to hold 16 elements.
138 */
139 public ArrayDeque() {
140 elements = new Object[16];
141 }
142
143 /**
144 * Constructs an empty array deque with an initial capacity
145 * sufficient to hold the specified number of elements.
146 *
147 * @param numElements lower bound on initial capacity of the deque
148 */
149 public ArrayDeque(int numElements) {
150 allocateElements(numElements);
151 }
152
153 /**
154 * Constructs a deque containing the elements of the specified
155 * collection, in the order they are returned by the collection's
156 * iterator. (The first element returned by the collection's
157 * iterator becomes the first element, or <i>front</i> of the
158 * deque.)
159 *
160 * @param c the collection whose elements are to be placed into the deque
161 * @throws NullPointerException if the specified collection is null
162 */
163 public ArrayDeque(Collection<? extends E> c) {
164 allocateElements(c.size());
165 addAll(c);
166 }
167
168 // The main insertion and extraction methods are addFirst,
169 // addLast, pollFirst, pollLast. The other methods are defined in
170 // terms of these.
171
172 /**
173 * Inserts the specified element at the front of this deque.
174 *
175 * @param e the element to add
176 * @throws NullPointerException if the specified element is null
177 */
178 public void addFirst(E e) {
179 if (e == null)
180 throw new NullPointerException();
181 elements[head = (head - 1) & (elements.length - 1)] = e;
182 if (head == tail)
183 doubleCapacity();
184 }
185
186 /**
187 * Inserts the specified element at the end of this deque.
188 *
189 * <p>This method is equivalent to {@link #add}.
190 *
191 * @param e the element to add
192 * @throws NullPointerException if the specified element is null
193 */
194 public void addLast(E e) {
195 if (e == null)
196 throw new NullPointerException();
197 elements[tail] = e;
198 if ( (tail = (tail + 1) & (elements.length - 1)) == head)
199 doubleCapacity();
200 }
201
202 /**
203 * Inserts the specified element at the front of this deque.
204 *
205 * @param e the element to add
206 * @return {@code true} (as specified by {@link Deque#offerFirst})
207 * @throws NullPointerException if the specified element is null
208 */
209 public boolean offerFirst(E e) {
210 addFirst(e);
211 return true;
212 }
213
214 /**
215 * Inserts the specified element at the end of this deque.
216 *
217 * @param e the element to add
218 * @return {@code true} (as specified by {@link Deque#offerLast})
219 * @throws NullPointerException if the specified element is null
220 */
221 public boolean offerLast(E e) {
222 addLast(e);
223 return true;
224 }
225
226 /**
227 * @throws NoSuchElementException {@inheritDoc}
228 */
229 public E removeFirst() {
230 E x = pollFirst();
231 if (x == null)
232 throw new NoSuchElementException();
233 return x;
234 }
235
236 /**
237 * @throws NoSuchElementException {@inheritDoc}
238 */
239 public E removeLast() {
240 E x = pollLast();
241 if (x == null)
242 throw new NoSuchElementException();
243 return x;
244 }
245
246 public E pollFirst() {
247 int h = head;
248 @SuppressWarnings("unchecked")
249 E result = (E) elements[h];
250 // Element is null if deque empty
251 if (result == null)
252 return null;
253 elements[h] = null; // Must null out slot
254 head = (h + 1) & (elements.length - 1);
255 return result;
256 }
257
258 public E pollLast() {
259 int t = (tail - 1) & (elements.length - 1);
260 @SuppressWarnings("unchecked")
261 E result = (E) elements[t];
262 if (result == null)
263 return null;
264 elements[t] = null;
265 tail = t;
266 return result;
267 }
268
269 /**
270 * @throws NoSuchElementException {@inheritDoc}
271 */
272 public E getFirst() {
273 @SuppressWarnings("unchecked")
274 E result = (E) elements[head];
275 if (result == null)
276 throw new NoSuchElementException();
277 return result;
278 }
279
280 /**
281 * @throws NoSuchElementException {@inheritDoc}
282 */
283 public E getLast() {
284 @SuppressWarnings("unchecked")
285 E result = (E) elements[(tail - 1) & (elements.length - 1)];
286 if (result == null)
287 throw new NoSuchElementException();
288 return result;
289 }
290
291 @SuppressWarnings("unchecked")
292 public E peekFirst() {
293 // elements[head] is null if deque empty
294 return (E) elements[head];
295 }
296
297 @SuppressWarnings("unchecked")
298 public E peekLast() {
299 return (E) elements[(tail - 1) & (elements.length - 1)];
300 }
301
302 /**
303 * Removes the first occurrence of the specified element in this
304 * deque (when traversing the deque from head to tail).
305 * If the deque does not contain the element, it is unchanged.
306 * More formally, removes the first element {@code e} such that
307 * {@code o.equals(e)} (if such an element exists).
308 * Returns {@code true} if this deque contained the specified element
309 * (or equivalently, if this deque changed as a result of the call).
310 *
311 * @param o element to be removed from this deque, if present
312 * @return {@code true} if the deque contained the specified element
313 */
314 public boolean removeFirstOccurrence(Object o) {
315 if (o == null)
316 return false;
317 int mask = elements.length - 1;
318 int i = head;
319 Object x;
320 while ( (x = elements[i]) != null) {
321 if (o.equals(x)) {
322 delete(i);
323 return true;
324 }
325 i = (i + 1) & mask;
326 }
327 return false;
328 }
329
330 /**
331 * Removes the last occurrence of the specified element in this
332 * deque (when traversing the deque from head to tail).
333 * If the deque does not contain the element, it is unchanged.
334 * More formally, removes the last element {@code e} such that
335 * {@code o.equals(e)} (if such an element exists).
336 * Returns {@code true} if this deque contained the specified element
337 * (or equivalently, if this deque changed as a result of the call).
338 *
339 * @param o element to be removed from this deque, if present
340 * @return {@code true} if the deque contained the specified element
341 */
342 public boolean removeLastOccurrence(Object o) {
343 if (o == null)
344 return false;
345 int mask = elements.length - 1;
346 int i = (tail - 1) & mask;
347 Object x;
348 while ( (x = elements[i]) != null) {
349 if (o.equals(x)) {
350 delete(i);
351 return true;
352 }
353 i = (i - 1) & mask;
354 }
355 return false;
356 }
357
358 // *** Queue methods ***
359
360 /**
361 * Inserts the specified element at the end of this deque.
362 *
363 * <p>This method is equivalent to {@link #addLast}.
364 *
365 * @param e the element to add
366 * @return {@code true} (as specified by {@link Collection#add})
367 * @throws NullPointerException if the specified element is null
368 */
369 public boolean add(E e) {
370 addLast(e);
371 return true;
372 }
373
374 /**
375 * Inserts the specified element at the end of this deque.
376 *
377 * <p>This method is equivalent to {@link #offerLast}.
378 *
379 * @param e the element to add
380 * @return {@code true} (as specified by {@link Queue#offer})
381 * @throws NullPointerException if the specified element is null
382 */
383 public boolean offer(E e) {
384 return offerLast(e);
385 }
386
387 /**
388 * Retrieves and removes the head of the queue represented by this deque.
389 *
390 * This method differs from {@link #poll poll} only in that it throws an
391 * exception if this deque is empty.
392 *
393 * <p>This method is equivalent to {@link #removeFirst}.
394 *
395 * @return the head of the queue represented by this deque
396 * @throws NoSuchElementException {@inheritDoc}
397 */
398 public E remove() {
399 return removeFirst();
400 }
401
402 /**
403 * Retrieves and removes the head of the queue represented by this deque
404 * (in other words, the first element of this deque), or returns
405 * {@code null} if this deque is empty.
406 *
407 * <p>This method is equivalent to {@link #pollFirst}.
408 *
409 * @return the head of the queue represented by this deque, or
410 * {@code null} if this deque is empty
411 */
412 public E poll() {
413 return pollFirst();
414 }
415
416 /**
417 * Retrieves, but does not remove, the head of the queue represented by
418 * this deque. This method differs from {@link #peek peek} only in
419 * that it throws an exception if this deque is empty.
420 *
421 * <p>This method is equivalent to {@link #getFirst}.
422 *
423 * @return the head of the queue represented by this deque
424 * @throws NoSuchElementException {@inheritDoc}
425 */
426 public E element() {
427 return getFirst();
428 }
429
430 /**
431 * Retrieves, but does not remove, the head of the queue represented by
432 * this deque, or returns {@code null} if this deque is empty.
433 *
434 * <p>This method is equivalent to {@link #peekFirst}.
435 *
436 * @return the head of the queue represented by this deque, or
437 * {@code null} if this deque is empty
438 */
439 public E peek() {
440 return peekFirst();
441 }
442
443 // *** Stack methods ***
444
445 /**
446 * Pushes an element onto the stack represented by this deque. In other
447 * words, inserts the element at the front of this deque.
448 *
449 * <p>This method is equivalent to {@link #addFirst}.
450 *
451 * @param e the element to push
452 * @throws NullPointerException if the specified element is null
453 */
454 public void push(E e) {
455 addFirst(e);
456 }
457
458 /**
459 * Pops an element from the stack represented by this deque. In other
460 * words, removes and returns the first element of this deque.
461 *
462 * <p>This method is equivalent to {@link #removeFirst()}.
463 *
464 * @return the element at the front of this deque (which is the top
465 * of the stack represented by this deque)
466 * @throws NoSuchElementException {@inheritDoc}
467 */
468 public E pop() {
469 return removeFirst();
470 }
471
472 private void checkInvariants() {
473 assert elements[tail] == null;
474 assert head == tail ? elements[head] == null :
475 (elements[head] != null &&
476 elements[(tail - 1) & (elements.length - 1)] != null);
477 assert elements[(head - 1) & (elements.length - 1)] == null;
478 }
479
480 /**
481 * Removes the element at the specified position in the elements array,
482 * adjusting head and tail as necessary. This can result in motion of
483 * elements backwards or forwards in the array.
484 *
485 * <p>This method is called delete rather than remove to emphasize
486 * that its semantics differ from those of {@link List#remove(int)}.
487 *
488 * @return true if elements moved backwards
489 */
490 private boolean delete(int i) {
491 // checkInvariants();
492 final Object[] elements = this.elements;
493 final int mask = elements.length - 1;
494 final int h = head;
495 final int t = tail;
496 final int front = (i - h) & mask;
497 final int back = (t - i) & mask;
498
499 // Invariant: head <= i < tail mod circularity
500 if (front >= ((t - h) & mask))
501 throw new ConcurrentModificationException();
502
503 // Optimize for least element motion
504 if (front < back) {
505 if (h <= i) {
506 System.arraycopy(elements, h, elements, h + 1, front);
507 } else { // Wrap around
508 System.arraycopy(elements, 0, elements, 1, i);
509 elements[0] = elements[mask];
510 System.arraycopy(elements, h, elements, h + 1, mask - h);
511 }
512 elements[h] = null;
513 head = (h + 1) & mask;
514 return false;
515 } else {
516 if (i < t) { // Copy the null tail as well
517 System.arraycopy(elements, i + 1, elements, i, back);
518 tail = t - 1;
519 } else { // Wrap around
520 System.arraycopy(elements, i + 1, elements, i, mask - i);
521 elements[mask] = elements[0];
522 System.arraycopy(elements, 1, elements, 0, t);
523 tail = (t - 1) & mask;
524 }
525 return true;
526 }
527 }
528
529 // *** Collection Methods ***
530
531 /**
532 * Returns the number of elements in this deque.
533 *
534 * @return the number of elements in this deque
535 */
536 public int size() {
537 return (tail - head) & (elements.length - 1);
538 }
539
540 /**
541 * Returns {@code true} if this deque contains no elements.
542 *
543 * @return {@code true} if this deque contains no elements
544 */
545 public boolean isEmpty() {
546 return head == tail;
547 }
548
549 /**
550 * Returns an iterator over the elements in this deque. The elements
551 * will be ordered from first (head) to last (tail). This is the same
552 * order that elements would be dequeued (via successive calls to
553 * {@link #remove} or popped (via successive calls to {@link #pop}).
554 *
555 * @return an iterator over the elements in this deque
556 */
557 public Iterator<E> iterator() {
558 return new DeqIterator();
559 }
560
561 public Iterator<E> descendingIterator() {
562 return new DescendingIterator();
563 }
564
565 private class DeqIterator implements Iterator<E> {
566 /**
567 * Index of element to be returned by subsequent call to next.
568 */
569 private int cursor = head;
570
571 /**
572 * Tail recorded at construction (also in remove), to stop
573 * iterator and also to check for comodification.
574 */
575 private int fence = tail;
576
577 /**
578 * Index of element returned by most recent call to next.
579 * Reset to -1 if element is deleted by a call to remove.
580 */
581 private int lastRet = -1;
582
583 public boolean hasNext() {
584 return cursor != fence;
585 }
586
587 public E next() {
588 if (cursor == fence)
589 throw new NoSuchElementException();
590 @SuppressWarnings("unchecked")
591 E result = (E) elements[cursor];
592 // This check doesn't catch all possible comodifications,
593 // but does catch the ones that corrupt traversal
594 if (tail != fence || result == null)
595 throw new ConcurrentModificationException();
596 lastRet = cursor;
597 cursor = (cursor + 1) & (elements.length - 1);
598 return result;
599 }
600
601 public void remove() {
602 if (lastRet < 0)
603 throw new IllegalStateException();
604 if (delete(lastRet)) { // if left-shifted, undo increment in next()
605 cursor = (cursor - 1) & (elements.length - 1);
606 fence = tail;
607 }
608 lastRet = -1;
609 }
610 }
611
612 /**
613 * This class is nearly a mirror-image of DeqIterator, using tail
614 * instead of head for initial cursor, and head instead of tail
615 * for fence.
616 */
617 private class DescendingIterator implements Iterator<E> {
618 private int cursor = tail;
619 private int fence = head;
620 private int lastRet = -1;
621
622 public boolean hasNext() {
623 return cursor != fence;
624 }
625
626 public E next() {
627 if (cursor == fence)
628 throw new NoSuchElementException();
629 cursor = (cursor - 1) & (elements.length - 1);
630 @SuppressWarnings("unchecked")
631 E result = (E) elements[cursor];
632 if (head != fence || result == null)
633 throw new ConcurrentModificationException();
634 lastRet = cursor;
635 return result;
636 }
637
638 public void remove() {
639 if (lastRet < 0)
640 throw new IllegalStateException();
641 if (!delete(lastRet)) {
642 cursor = (cursor + 1) & (elements.length - 1);
643 fence = head;
644 }
645 lastRet = -1;
646 }
647 }
648
649 /**
650 * Returns {@code true} if this deque contains the specified element.
651 * More formally, returns {@code true} if and only if this deque contains
652 * at least one element {@code e} such that {@code o.equals(e)}.
653 *
654 * @param o object to be checked for containment in this deque
655 * @return {@code true} if this deque contains the specified element
656 */
657 public boolean contains(Object o) {
658 if (o == null)
659 return false;
660 int mask = elements.length - 1;
661 int i = head;
662 Object x;
663 while ( (x = elements[i]) != null) {
664 if (o.equals(x))
665 return true;
666 i = (i + 1) & mask;
667 }
668 return false;
669 }
670
671 /**
672 * Removes a single instance of the specified element from this deque.
673 * If the deque does not contain the element, it is unchanged.
674 * More formally, removes the first element {@code e} such that
675 * {@code o.equals(e)} (if such an element exists).
676 * Returns {@code true} if this deque contained the specified element
677 * (or equivalently, if this deque changed as a result of the call).
678 *
679 * <p>This method is equivalent to {@link #removeFirstOccurrence}.
680 *
681 * @param o element to be removed from this deque, if present
682 * @return {@code true} if this deque contained the specified element
683 */
684 public boolean remove(Object o) {
685 return removeFirstOccurrence(o);
686 }
687
688 /**
689 * Removes all of the elements from this deque.
690 * The deque will be empty after this call returns.
691 */
692 public void clear() {
693 int h = head;
694 int t = tail;
695 if (h != t) { // clear all cells
696 head = tail = 0;
697 int i = h;
698 int mask = elements.length - 1;
699 do {
700 elements[i] = null;
701 i = (i + 1) & mask;
702 } while (i != t);
703 }
704 }
705
706 /**
707 * Returns an array containing all of the elements in this deque
708 * in proper sequence (from first to last element).
709 *
710 * <p>The returned array will be "safe" in that no references to it are
711 * maintained by this deque. (In other words, this method must allocate
712 * a new array). The caller is thus free to modify the returned array.
713 *
714 * <p>This method acts as bridge between array-based and collection-based
715 * APIs.
716 *
717 * @return an array containing all of the elements in this deque
718 */
719 public Object[] toArray() {
720 final int head = this.head;
721 final int tail = this.tail;
722 boolean wrap = (tail < head);
723 int end = wrap ? tail + elements.length : tail;
724 Object[] a = Arrays.copyOfRange(elements, head, end);
725 if (wrap)
726 System.arraycopy(elements, 0, a, elements.length - head, tail);
727 return a;
728 }
729
730 /**
731 * Returns an array containing all of the elements in this deque in
732 * proper sequence (from first to last element); the runtime type of the
733 * returned array is that of the specified array. If the deque fits in
734 * the specified array, it is returned therein. Otherwise, a new array
735 * is allocated with the runtime type of the specified array and the
736 * size of this deque.
737 *
738 * <p>If this deque fits in the specified array with room to spare
739 * (i.e., the array has more elements than this deque), the element in
740 * the array immediately following the end of the deque is set to
741 * {@code null}.
742 *
743 * <p>Like the {@link #toArray()} method, this method acts as bridge between
744 * array-based and collection-based APIs. Further, this method allows
745 * precise control over the runtime type of the output array, and may,
746 * under certain circumstances, be used to save allocation costs.
747 *
748 * <p>Suppose {@code x} is a deque known to contain only strings.
749 * The following code can be used to dump the deque into a newly
750 * allocated array of {@code String}:
751 *
752 * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
753 *
754 * Note that {@code toArray(new Object[0])} is identical in function to
755 * {@code toArray()}.
756 *
757 * @param a the array into which the elements of the deque are to
758 * be stored, if it is big enough; otherwise, a new array of the
759 * same runtime type is allocated for this purpose
760 * @return an array containing all of the elements in this deque
761 * @throws ArrayStoreException if the runtime type of the specified array
762 * is not a supertype of the runtime type of every element in
763 * this deque
764 * @throws NullPointerException if the specified array is null
765 */
766 @SuppressWarnings("unchecked")
767 public <T> T[] toArray(T[] a) {
768 final int head = this.head;
769 final int tail = this.tail;
770 boolean wrap = (tail < head);
771 int size = (tail - head) + (wrap ? elements.length : 0);
772 int firstLeg = size - (wrap ? tail : 0);
773 int len = a.length;
774 if (size > len) {
775 a = (T[]) Arrays.copyOfRange(elements, head, head + size,
776 a.getClass());
777 } else {
778 System.arraycopy(elements, head, a, 0, firstLeg);
779 if (size < len)
780 a[size] = null;
781 }
782 if (wrap)
783 System.arraycopy(elements, 0, a, firstLeg, tail);
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 private static final long serialVersionUID = 2340985798034038923L;
806
807 /**
808 * Saves this deque to a stream (that is, serializes it).
809 *
810 * @serialData The current size ({@code int}) of the deque,
811 * followed by all of its elements (each an object reference) in
812 * first-to-last order.
813 */
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 * Reconstitutes this deque from a stream (that is, deserializes it).
829 */
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 }