ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166x/ArrayDeque.java
Revision: 1.13
Committed: Sun Jan 18 20:17:33 2015 UTC (9 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.12: +1 -0 lines
Log Message:
exactly one blank line before and after package statements

File Contents

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