ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166x/ArrayDeque.java
Revision: 1.3
Committed: Mon Nov 16 04:16:42 2009 UTC (14 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.2: +9 -9 lines
Log Message:
whitespace

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 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 * {@link Stack} when used as as a stack, and faster than {@link LinkedList}
17 * 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 * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
38 * 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 private void allocateElements(int numElements) {
94 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 assert head == tail;
118 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 if (head == tail)
198 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 elements[t] = null;
247 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 public E getFirst() {
336 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 public E getLast() {
351 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 * <p>This method is equivalent to {@link #getFirst}
482 *
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 return getFirst();
488 }
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 * words, removes and returns the the first element of this deque.
508 *
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 *
527 * @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 *
572 * @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 } while(i != t);
671 }
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 * in the correct order
680 */
681 public Object[] toArray() {
682 return copyElements(new Object[size()]);
683 }
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 * be stored, if it is big enough; otherwise, a new array of the
698 * same runtime type is allocated for this purpose
699 * @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 copyElements(a);
709 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 try {
723 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 } catch (CloneNotSupportedException e) {
730 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 }