ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/ArrayDeque.java
Revision: 1.4
Committed: Tue Mar 8 19:07:39 2005 UTC (19 years, 2 months ago) by dl
Branch: MAIN
Changes since 1.3: +2 -2 lines
Log Message:
Copyedit pass

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