ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166x/ArrayDeque.java
Revision: 1.8
Committed: Tue Mar 15 19:47:02 2011 UTC (13 years, 1 month ago) by jsr166
Branch: MAIN
CVS Tags: jdk7-compat, release-1_7_0
Changes since 1.7: +1 -1 lines
Log Message:
Update Creative Commons license URL in legal notices

File Contents

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