KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > ArrayDeque


1 /*
2  * @(#)ArrayDeque.java 1.6 06/04/21
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.util;
9 import java.io.*;
10
11 /**
12  * Resizable-array implementation of the {@link Deque} interface. Array
13  * deques have no capacity restrictions; they grow as necessary to support
14  * usage. They are not thread-safe; in the absence of external
15  * synchronization, they do not support concurrent access by multiple threads.
16  * Null elements are prohibited. This class is likely to be faster than
17  * {@link Stack} when used as a stack, and faster than {@link LinkedList}
18  * when used as a queue.
19  *
20  * <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time.
21  * Exceptions include {@link #remove(Object) remove}, {@link
22  * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence
23  * removeLastOccurrence}, {@link #contains contains}, {@link #iterator
24  * iterator.remove()}, and the bulk operations, all of which run in linear
25  * time.
26  *
27  * <p>The iterators returned by this class's <tt>iterator</tt> method are
28  * <i>fail-fast</i>: If the deque is modified at any time after the iterator
29  * is created, in any way except through the iterator's own <tt>remove</tt>
30  * method, the iterator will generally throw a {@link
31  * ConcurrentModificationException}. Thus, in the face of concurrent
32  * modification, the iterator fails quickly and cleanly, rather than risking
33  * arbitrary, non-deterministic behavior at an undetermined time in the
34  * future.
35  *
36  * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
37  * as it is, generally speaking, impossible to make any hard guarantees in the
38  * presence of unsynchronized concurrent modification. Fail-fast iterators
39  * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
40  * Therefore, it would be wrong to write a program that depended on this
41  * exception for its correctness: <i>the fail-fast behavior of iterators
42  * should be used only to detect bugs.</i>
43  *
44  * <p>This class and its iterator implement all of the
45  * <em>optional</em> methods of the {@link Collection} and {@link
46  * Iterator} interfaces.
47  *
48  * <p>This class is a member of the
49  * <a HREF="{@docRoot}/../technotes/guides/collections/index.html">
50  * Java Collections Framework</a>.
51  *
52  * @author Josh Bloch and Doug Lea
53  * @since 1.6
54  * @param <E> the type of elements held in this collection
55  */

56 public class ArrayDeque<E> extends AbstractCollection JavaDoc<E>
57                            implements Deque JavaDoc<E>, Cloneable JavaDoc, Serializable
58 {
59     /**
60      * The array in which the elements of the deque are stored.
61      * The capacity of the deque is the length of this array, which is
62      * always a power of two. The array is never allowed to become
63      * full, except transiently within an addX method where it is
64      * resized (see doubleCapacity) immediately upon becoming full,
65      * thus avoiding head and tail wrapping around to equal each
66      * other. We also guarantee that all array cells not holding
67      * deque elements are always null.
68      */

69     private transient E[] elements;
70
71     /**
72      * The index of the element at the head of the deque (which is the
73      * element that would be removed by remove() or pop()); or an
74      * arbitrary number equal to tail if the deque is empty.
75      */

76     private transient int head;
77
78     /**
79      * The index at which the next element would be added to the tail
80      * of the deque (via addLast(E), add(E), or push(E)).
81      */

82     private transient int tail;
83
84     /**
85      * The minimum capacity that we'll use for a newly created deque.
86      * Must be a power of 2.
87      */

88     private static final int MIN_INITIAL_CAPACITY = 8;
89
90     // ****** Array allocation and resizing utilities ******
91

92     /**
93      * Allocate empty array to hold the given number of elements.
94      *
95      * @param numElements the number of elements to hold
96      */

97     private void allocateElements(int numElements) {
98         int initialCapacity = MIN_INITIAL_CAPACITY;
99         // Find the best power of two to hold elements.
100
// Tests "<=" because arrays aren't kept full.
101
if (numElements >= initialCapacity) {
102             initialCapacity = numElements;
103             initialCapacity |= (initialCapacity >>> 1);
104             initialCapacity |= (initialCapacity >>> 2);
105             initialCapacity |= (initialCapacity >>> 4);
106             initialCapacity |= (initialCapacity >>> 8);
107             initialCapacity |= (initialCapacity >>> 16);
108             initialCapacity++;
109
110             if (initialCapacity < 0) // Too many elements, must back off
111
initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
112
}
113         elements = (E[]) new Object JavaDoc[initialCapacity];
114     }
115
116     /**
117      * Double the capacity of this deque. Call only when full, i.e.,
118      * when head and tail have wrapped around to become equal.
119      */

120     private void doubleCapacity() {
121         assert head == tail;
122         int p = head;
123         int n = elements.length;
124         int r = n - p; // number of elements to the right of p
125
int newCapacity = n << 1;
126         if (newCapacity < 0)
127             throw new IllegalStateException JavaDoc("Sorry, deque too big");
128         Object JavaDoc[] a = new Object JavaDoc[newCapacity];
129         System.arraycopy(elements, p, a, 0, r);
130         System.arraycopy(elements, 0, a, r, p);
131         elements = (E[])a;
132         head = 0;
133         tail = n;
134     }
135
136     /**
137      * Copies the elements from our element array into the specified array,
138      * in order (from first to last element in the deque). It is assumed
139      * that the array is large enough to hold all elements in the deque.
140      *
141      * @return its argument
142      */

143     private <T> T[] copyElements(T[] a) {
144         if (head < tail) {
145             System.arraycopy(elements, head, a, 0, size());
146         } else if (head > tail) {
147             int headPortionLen = elements.length - head;
148             System.arraycopy(elements, head, a, 0, headPortionLen);
149             System.arraycopy(elements, 0, a, headPortionLen, tail);
150         }
151         return a;
152     }
153
154     /**
155      * Constructs an empty array deque with an initial capacity
156      * sufficient to hold 16 elements.
157      */

158     public ArrayDeque() {
159         elements = (E[]) new Object JavaDoc[16];
160     }
161
162     /**
163      * Constructs an empty array deque with an initial capacity
164      * sufficient to hold the specified number of elements.
165      *
166      * @param numElements lower bound on initial capacity of the deque
167      */

168     public ArrayDeque(int numElements) {
169         allocateElements(numElements);
170     }
171
172     /**
173      * Constructs a deque containing the elements of the specified
174      * collection, in the order they are returned by the collection's
175      * iterator. (The first element returned by the collection's
176      * iterator becomes the first element, or <i>front</i> of the
177      * deque.)
178      *
179      * @param c the collection whose elements are to be placed into the deque
180      * @throws NullPointerException if the specified collection is null
181      */

182     public ArrayDeque(Collection JavaDoc<? extends E> c) {
183         allocateElements(c.size());
184         addAll(c);
185     }
186
187     // The main insertion and extraction methods are addFirst,
188
// addLast, pollFirst, pollLast. The other methods are defined in
189
// terms of these.
190

191     /**
192      * Inserts the specified element at the front of this deque.
193      *
194      * @param e the element to add
195      * @throws NullPointerException if the specified element is null
196      */

197     public void addFirst(E e) {
198         if (e == null)
199             throw new NullPointerException JavaDoc();
200         elements[head = (head - 1) & (elements.length - 1)] = e;
201         if (head == tail)
202             doubleCapacity();
203     }
204
205     /**
206      * Inserts the specified element at the end of this deque.
207      *
208      * <p>This method is equivalent to {@link #add}.
209      *
210      * @param e the element to add
211      * @throws NullPointerException if the specified element is null
212      */

213     public void addLast(E e) {
214         if (e == null)
215             throw new NullPointerException JavaDoc();
216         elements[tail] = e;
217         if ( (tail = (tail + 1) & (elements.length - 1)) == head)
218             doubleCapacity();
219     }
220
221     /**
222      * Inserts the specified element at the front of this deque.
223      *
224      * @param e the element to add
225      * @return <tt>true</tt> (as specified by {@link Deque#offerFirst})
226      * @throws NullPointerException if the specified element is null
227      */

228     public boolean offerFirst(E e) {
229         addFirst(e);
230         return true;
231     }
232
233     /**
234      * Inserts the specified element at the end of this deque.
235      *
236      * @param e the element to add
237      * @return <tt>true</tt> (as specified by {@link Deque#offerLast})
238      * @throws NullPointerException if the specified element is null
239      */

240     public boolean offerLast(E e) {
241         addLast(e);
242         return true;
243     }
244
245     /**
246      * @throws NoSuchElementException {@inheritDoc}
247      */

248     public E removeFirst() {
249         E x = pollFirst();
250         if (x == null)
251             throw new NoSuchElementException JavaDoc();
252         return x;
253     }
254
255     /**
256      * @throws NoSuchElementException {@inheritDoc}
257      */

258     public E removeLast() {
259         E x = pollLast();
260         if (x == null)
261             throw new NoSuchElementException JavaDoc();
262         return x;
263     }
264
265     public E pollFirst() {
266         int h = head;
267         E result = elements[h]; // Element is null if deque empty
268
if (result == null)
269             return null;
270         elements[h] = null; // Must null out slot
271
head = (h + 1) & (elements.length - 1);
272         return result;
273     }
274
275     public E pollLast() {
276         int t = (tail - 1) & (elements.length - 1);
277         E result = 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         E x = elements[head];
290         if (x == null)
291             throw new NoSuchElementException JavaDoc();
292         return x;
293     }
294
295     /**
296      * @throws NoSuchElementException {@inheritDoc}
297      */

298     public E getLast() {
299         E x = elements[(tail - 1) & (elements.length - 1)];
300         if (x == null)
301             throw new NoSuchElementException JavaDoc();
302         return x;
303     }
304
305     public E peekFirst() {
306         return elements[head]; // elements[head] is null if deque empty
307
}
308
309     public E peekLast() {
310         return elements[(tail - 1) & (elements.length - 1)];
311     }
312
313     /**
314      * Removes the first occurrence of the specified element in this
315      * deque (when traversing the deque from head to tail).
316      * If the deque does not contain the element, it is unchanged.
317      * More formally, removes the first element <tt>e</tt> such that
318      * <tt>o.equals(e)</tt> (if such an element exists).
319      * Returns <tt>true</tt> if this deque contained the specified element
320      * (or equivalently, if this deque changed as a result of the call).
321      *
322      * @param o element to be removed from this deque, if present
323      * @return <tt>true</tt> if the deque contained the specified element
324      */

325     public boolean removeFirstOccurrence(Object JavaDoc o) {
326         if (o == null)
327             return false;
328         int mask = elements.length - 1;
329         int i = head;
330         E x;
331         while ( (x = elements[i]) != null) {
332             if (o.equals(x)) {
333                 delete(i);
334                 return true;
335             }
336             i = (i + 1) & mask;
337         }
338         return false;
339     }
340
341     /**
342      * Removes the last occurrence of the specified element in this
343      * deque (when traversing the deque from head to tail).
344      * If the deque does not contain the element, it is unchanged.
345      * More formally, removes the last element <tt>e</tt> such that
346      * <tt>o.equals(e)</tt> (if such an element exists).
347      * Returns <tt>true</tt> if this deque contained the specified element
348      * (or equivalently, if this deque changed as a result of the call).
349      *
350      * @param o element to be removed from this deque, if present
351      * @return <tt>true</tt> if the deque contained the specified element
352      */

353     public boolean removeLastOccurrence(Object JavaDoc o) {
354         if (o == null)
355             return false;
356         int mask = elements.length - 1;
357         int i = (tail - 1) & mask;
358         E x;
359         while ( (x = elements[i]) != null) {
360             if (o.equals(x)) {
361                 delete(i);
362                 return true;
363             }
364             i = (i - 1) & mask;
365         }
366         return false;
367     }
368
369     // *** Queue methods ***
370

371     /**
372      * Inserts the specified element at the end of this deque.
373      *
374      * <p>This method is equivalent to {@link #addLast}.
375      *
376      * @param e the element to add
377      * @return <tt>true</tt> (as specified by {@link Collection#add})
378      * @throws NullPointerException if the specified element is null
379      */

380     public boolean add(E e) {
381         addLast(e);
382         return true;
383     }
384
385     /**
386      * Inserts the specified element at the end of this deque.
387      *
388      * <p>This method is equivalent to {@link #offerLast}.
389      *
390      * @param e the element to add
391      * @return <tt>true</tt> (as specified by {@link Queue#offer})
392      * @throws NullPointerException if the specified element is null
393      */

394     public boolean offer(E e) {
395         return offerLast(e);
396     }
397
398     /**
399      * Retrieves and removes the head of the queue represented by this deque.
400      *
401      * This method differs from {@link #poll poll} only in that it throws an
402      * exception if this deque is empty.
403      *
404      * <p>This method is equivalent to {@link #removeFirst}.
405      *
406      * @return the head of the queue represented by this deque
407      * @throws NoSuchElementException {@inheritDoc}
408      */

409     public E remove() {
410         return removeFirst();
411     }
412
413     /**
414      * Retrieves and removes the head of the queue represented by this deque
415      * (in other words, the first element of this deque), or returns
416      * <tt>null</tt> if this deque is empty.
417      *
418      * <p>This method is equivalent to {@link #pollFirst}.
419      *
420      * @return the head of the queue represented by this deque, or
421      * <tt>null</tt> if this deque is empty
422      */

423     public E poll() {
424         return pollFirst();
425     }
426
427     /**
428      * Retrieves, but does not remove, the head of the queue represented by
429      * this deque. This method differs from {@link #peek peek} only in
430      * that it throws an exception if this deque is empty.
431      *
432      * <p>This method is equivalent to {@link #getFirst}.
433      *
434      * @return the head of the queue represented by this deque
435      * @throws NoSuchElementException {@inheritDoc}
436      */

437     public E element() {
438         return getFirst();
439     }
440
441     /**
442      * Retrieves, but does not remove, the head of the queue represented by
443      * this deque, or returns <tt>null</tt> if this deque is empty.
444      *
445      * <p>This method is equivalent to {@link #peekFirst}.
446      *
447      * @return the head of the queue represented by this deque, or
448      * <tt>null</tt> if this deque is empty
449      */

450     public E peek() {
451         return peekFirst();
452     }
453
454     // *** Stack methods ***
455

456     /**
457      * Pushes an element onto the stack represented by this deque. In other
458      * words, inserts the element at the front of this deque.
459      *
460      * <p>This method is equivalent to {@link #addFirst}.
461      *
462      * @param e the element to push
463      * @throws NullPointerException if the specified element is null
464      */

465     public void push(E e) {
466         addFirst(e);
467     }
468
469     /**
470      * Pops an element from the stack represented by this deque. In other
471      * words, removes and returns the first element of this deque.
472      *
473      * <p>This method is equivalent to {@link #removeFirst()}.
474      *
475      * @return the element at the front of this deque (which is the top
476      * of the stack represented by this deque)
477      * @throws NoSuchElementException {@inheritDoc}
478      */

479     public E pop() {
480         return removeFirst();
481     }
482
483     private void checkInvariants() {
484     assert elements[tail] == null;
485     assert head == tail ? elements[head] == null :
486         (elements[head] != null &&
487          elements[(tail - 1) & (elements.length - 1)] != null);
488     assert elements[(head - 1) & (elements.length - 1)] == null;
489     }
490
491     /**
492      * Removes the element at the specified position in the elements array,
493      * adjusting head and tail as necessary. This can result in motion of
494      * elements backwards or forwards in the array.
495      *
496      * <p>This method is called delete rather than remove to emphasize
497      * that its semantics differ from those of {@link List#remove(int)}.
498      *
499      * @return true if elements moved backwards
500      */

501     private boolean delete(int i) {
502     checkInvariants();
503     final E[] elements = this.elements;
504     final int mask = elements.length - 1;
505     final int h = head;
506     final int t = tail;
507     final int front = (i - h) & mask;
508     final int back = (t - i) & mask;
509
510     // Invariant: head <= i < tail mod circularity
511
if (front >= ((t - h) & mask))
512         throw new ConcurrentModificationException JavaDoc();
513
514     // Optimize for least element motion
515
if (front < back) {
516         if (h <= i) {
517         System.arraycopy(elements, h, elements, h + 1, front);
518         } else { // Wrap around
519
System.arraycopy(elements, 0, elements, 1, i);
520         elements[0] = elements[mask];
521         System.arraycopy(elements, h, elements, h + 1, mask - h);
522         }
523         elements[h] = null;
524         head = (h + 1) & mask;
525         return false;
526     } else {
527         if (i < t) { // Copy the null tail as well
528
System.arraycopy(elements, i + 1, elements, i, back);
529         tail = t - 1;
530         } else { // Wrap around
531
System.arraycopy(elements, i + 1, elements, i, mask - i);
532         elements[mask] = elements[0];
533         System.arraycopy(elements, 1, elements, 0, t);
534         tail = (t - 1) & mask;
535         }
536         return true;
537     }
538     }
539
540     // *** Collection Methods ***
541

542     /**
543      * Returns the number of elements in this deque.
544      *
545      * @return the number of elements in this deque
546      */

547     public int size() {
548         return (tail - head) & (elements.length - 1);
549     }
550
551     /**
552      * Returns <tt>true</tt> if this deque contains no elements.
553      *
554      * @return <tt>true</tt> if this deque contains no elements
555      */

556     public boolean isEmpty() {
557         return head == tail;
558     }
559
560     /**
561      * Returns an iterator over the elements in this deque. The elements
562      * will be ordered from first (head) to last (tail). This is the same
563      * order that elements would be dequeued (via successive calls to
564      * {@link #remove} or popped (via successive calls to {@link #pop}).
565      *
566      * @return an iterator over the elements in this deque
567      */

568     public Iterator JavaDoc<E> iterator() {
569         return new DeqIterator();
570     }
571
572     public Iterator JavaDoc<E> descendingIterator() {
573         return new DescendingIterator();
574     }
575
576     private class DeqIterator implements Iterator JavaDoc<E> {
577         /**
578          * Index of element to be returned by subsequent call to next.
579          */

580         private int cursor = head;
581
582         /**
583          * Tail recorded at construction (also in remove), to stop
584          * iterator and also to check for comodification.
585          */

586         private int fence = tail;
587
588         /**
589          * Index of element returned by most recent call to next.
590          * Reset to -1 if element is deleted by a call to remove.
591          */

592         private int lastRet = -1;
593
594         public boolean hasNext() {
595             return cursor != fence;
596         }
597
598         public E next() {
599             if (cursor == fence)
600                 throw new NoSuchElementException JavaDoc();
601             E result = elements[cursor];
602             // This check doesn't catch all possible comodifications,
603
// but does catch the ones that corrupt traversal
604
if (tail != fence || result == null)
605                 throw new ConcurrentModificationException JavaDoc();
606             lastRet = cursor;
607             cursor = (cursor + 1) & (elements.length - 1);
608             return result;
609         }
610
611         public void remove() {
612             if (lastRet < 0)
613                 throw new IllegalStateException JavaDoc();
614             if (delete(lastRet)) { // if left-shifted, undo increment in next()
615
cursor = (cursor - 1) & (elements.length - 1);
616         fence = tail;
617         }
618             lastRet = -1;
619         }
620     }
621
622     private class DescendingIterator implements Iterator JavaDoc<E> {
623         /*
624          * This class is nearly a mirror-image of DeqIterator, using
625          * tail instead of head for initial cursor, and head instead of
626          * tail for fence.
627          */

628         private int cursor = tail;
629         private int fence = head;
630         private int lastRet = -1;
631
632         public boolean hasNext() {
633             return cursor != fence;
634         }
635
636         public E next() {
637             if (cursor == fence)
638                 throw new NoSuchElementException JavaDoc();
639             cursor = (cursor - 1) & (elements.length - 1);
640         E result = elements[cursor];
641             if (head != fence || result == null)
642                 throw new ConcurrentModificationException JavaDoc();
643             lastRet = cursor;
644             return result;
645         }
646
647         public void remove() {
648             if (lastRet < 0)
649                 throw new IllegalStateException JavaDoc();
650             if (!delete(lastRet)) {
651                 cursor = (cursor + 1) & (elements.length - 1);
652         fence = head;
653         }
654             lastRet = -1;
655         }
656     }
657
658     /**
659      * Returns <tt>true</tt> if this deque contains the specified element.
660      * More formally, returns <tt>true</tt> if and only if this deque contains
661      * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
662      *
663      * @param o object to be checked for containment in this deque
664      * @return <tt>true</tt> if this deque contains the specified element
665      */

666     public boolean contains(Object JavaDoc o) {
667         if (o == null)
668             return false;
669         int mask = elements.length - 1;
670         int i = head;
671         E x;
672         while ( (x = elements[i]) != null) {
673             if (o.equals(x))
674                 return true;
675             i = (i + 1) & mask;
676         }
677         return false;
678     }
679
680     /**
681      * Removes a single instance of the specified element from this deque.
682      * If the deque does not contain the element, it is unchanged.
683      * More formally, removes the first element <tt>e</tt> such that
684      * <tt>o.equals(e)</tt> (if such an element exists).
685      * Returns <tt>true</tt> if this deque contained the specified element
686      * (or equivalently, if this deque changed as a result of the call).
687      *
688      * <p>This method is equivalent to {@link #removeFirstOccurrence}.
689      *
690      * @param o element to be removed from this deque, if present
691      * @return <tt>true</tt> if this deque contained the specified element
692      */

693     public boolean remove(Object JavaDoc o) {
694         return removeFirstOccurrence(o);
695     }
696
697     /**
698      * Removes all of the elements from this deque.
699      * The deque will be empty after this call returns.
700      */

701     public void clear() {
702         int h = head;
703         int t = tail;
704         if (h != t) { // clear all cells
705
head = tail = 0;
706             int i = h;
707             int mask = elements.length - 1;
708             do {
709                 elements[i] = null;
710                 i = (i + 1) & mask;
711             } while (i != t);
712         }
713     }
714
715     /**
716      * Returns an array containing all of the elements in this deque
717      * in proper sequence (from first to last element).
718      *
719      * <p>The returned array will be "safe" in that no references to it are
720      * maintained by this deque. (In other words, this method must allocate
721      * a new array). The caller is thus free to modify the returned array.
722      *
723      * <p>This method acts as bridge between array-based and collection-based
724      * APIs.
725      *
726      * @return an array containing all of the elements in this deque
727      */

728     public Object JavaDoc[] toArray() {
729     return copyElements(new Object JavaDoc[size()]);
730     }
731
732     /**
733      * Returns an array containing all of the elements in this deque in
734      * proper sequence (from first to last element); the runtime type of the
735      * returned array is that of the specified array. If the deque fits in
736      * the specified array, it is returned therein. Otherwise, a new array
737      * is allocated with the runtime type of the specified array and the
738      * size of this deque.
739      *
740      * <p>If this deque fits in the specified array with room to spare
741      * (i.e., the array has more elements than this deque), the element in
742      * the array immediately following the end of the deque is set to
743      * <tt>null</tt>.
744      *
745      * <p>Like the {@link #toArray()} method, this method acts as bridge between
746      * array-based and collection-based APIs. Further, this method allows
747      * precise control over the runtime type of the output array, and may,
748      * under certain circumstances, be used to save allocation costs.
749      *
750      * <p>Suppose <tt>x</tt> is a deque known to contain only strings.
751      * The following code can be used to dump the deque into a newly
752      * allocated array of <tt>String</tt>:
753      *
754      * <pre>
755      * String[] y = x.toArray(new String[0]);</pre>
756      *
757      * Note that <tt>toArray(new Object[0])</tt> is identical in function to
758      * <tt>toArray()</tt>.
759      *
760      * @param a the array into which the elements of the deque are to
761      * be stored, if it is big enough; otherwise, a new array of the
762      * same runtime type is allocated for this purpose
763      * @return an array containing all of the elements in this deque
764      * @throws ArrayStoreException if the runtime type of the specified array
765      * is not a supertype of the runtime type of every element in
766      * this deque
767      * @throws NullPointerException if the specified array is null
768      */

769     public <T> T[] toArray(T[] a) {
770         int size = size();
771         if (a.length < size)
772             a = (T[])java.lang.reflect.Array.newInstance(
773                     a.getClass().getComponentType(), size);
774     copyElements(a);
775         if (a.length > size)
776             a[size] = null;
777         return a;
778     }
779
780     // *** Object methods ***
781

782     /**
783      * Returns a copy of this deque.
784      *
785      * @return a copy of this deque
786      */

787     public ArrayDeque JavaDoc<E> clone() {
788         try {
789             ArrayDeque JavaDoc<E> result = (ArrayDeque JavaDoc<E>) super.clone();
790             result.elements = Arrays.copyOf(elements, elements.length);
791             return result;
792
793         } catch (CloneNotSupportedException JavaDoc e) {
794             throw new AssertionError JavaDoc();
795         }
796     }
797
798     /**
799      * Appease the serialization gods.
800      */

801     private static final long serialVersionUID = 2340985798034038923L;
802
803     /**
804      * Serialize this deque.
805      *
806      * @serialData The current size (<tt>int</tt>) of the deque,
807      * followed by all of its elements (each an object reference) in
808      * first-to-last order.
809      */

810     private void writeObject(ObjectOutputStream s) throws IOException {
811         s.defaultWriteObject();
812
813         // Write out size
814
s.writeInt(size());
815
816         // Write out elements in order.
817
int mask = elements.length - 1;
818         for (int i = head; i != tail; i = (i + 1) & mask)
819             s.writeObject(elements[i]);
820     }
821
822     /**
823      * Deserialize this deque.
824      */

825     private void readObject(ObjectInputStream s)
826             throws IOException, ClassNotFoundException JavaDoc {
827         s.defaultReadObject();
828
829         // Read in size and allocate array
830
int size = s.readInt();
831         allocateElements(size);
832         head = 0;
833         tail = size;
834
835         // Read in all elements in the proper order.
836
for (int i = 0; i < size; i++)
837             elements[i] = (E)s.readObject();
838     }
839 }
840
Popular Tags