ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/ArrayDeque.java
Revision: 1.83
Committed: Sun Oct 23 00:28:41 2016 UTC (7 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.82: +2 -2 lines
Log Message:
fix placement of checkInvariants()

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 java.util;
7
8 import java.io.Serializable;
9 import java.util.function.Consumer;
10 import java.util.function.Predicate;
11 import java.util.function.UnaryOperator;
12
13 /**
14 * Resizable-array implementation of the {@link Deque} interface. Array
15 * deques have no capacity restrictions; they grow as necessary to support
16 * usage. They are not thread-safe; in the absence of external
17 * synchronization, they do not support concurrent access by multiple threads.
18 * Null elements are prohibited. This class is likely to be faster than
19 * {@link Stack} when used as a stack, and faster than {@link LinkedList}
20 * when used as a queue.
21 *
22 * <p>Most {@code ArrayDeque} operations run in amortized constant time.
23 * Exceptions include
24 * {@link #remove(Object) remove},
25 * {@link #removeFirstOccurrence removeFirstOccurrence},
26 * {@link #removeLastOccurrence removeLastOccurrence},
27 * {@link #contains contains},
28 * {@link #iterator iterator.remove()},
29 * and the bulk operations, all of which run in linear time.
30 *
31 * <p>The iterators returned by this class's {@link #iterator() iterator}
32 * method are <em>fail-fast</em>: If the deque is modified at any time after
33 * the iterator is created, in any way except through the iterator's own
34 * {@code remove} method, the iterator will generally throw a {@link
35 * ConcurrentModificationException}. Thus, in the face of concurrent
36 * modification, the iterator fails quickly and cleanly, rather than risking
37 * arbitrary, non-deterministic behavior at an undetermined time in the
38 * future.
39 *
40 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
41 * as it is, generally speaking, impossible to make any hard guarantees in the
42 * presence of unsynchronized concurrent modification. Fail-fast iterators
43 * throw {@code ConcurrentModificationException} on a best-effort basis.
44 * Therefore, it would be wrong to write a program that depended on this
45 * exception for its correctness: <i>the fail-fast behavior of iterators
46 * should be used only to detect bugs.</i>
47 *
48 * <p>This class and its iterator implement all of the
49 * <em>optional</em> methods of the {@link Collection} and {@link
50 * Iterator} interfaces.
51 *
52 * <p>This class is a member of the
53 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
54 * Java Collections Framework</a>.
55 *
56 * @author Josh Bloch and Doug Lea
57 * @param <E> the type of elements held in this deque
58 * @since 1.6
59 */
60 public class ArrayDeque<E> extends AbstractCollection<E>
61 implements Deque<E>, Cloneable, Serializable
62 {
63 /**
64 * The array in which the elements of the deque are stored.
65 * We guarantee that all array cells not holding deque elements
66 * are always null.
67 */
68 transient Object[] elements;
69
70 /**
71 * The index of the element at the head of the deque (which is the
72 * element that would be removed by remove() or pop()); or an
73 * arbitrary number 0 <= head < elements.length if the deque is empty.
74 */
75 transient int head;
76
77 /** Number of elements in this collection. */
78 transient int size;
79
80 /**
81 * The maximum size of array to allocate.
82 * Some VMs reserve some header words in an array.
83 * Attempts to allocate larger arrays may result in
84 * OutOfMemoryError: Requested array size exceeds VM limit
85 */
86 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
87
88 /**
89 * Increases the capacity of this deque by at least the given amount.
90 *
91 * @param needed the required minimum extra capacity; must be positive
92 */
93 private void grow(int needed) {
94 // overflow-conscious code
95 // checkInvariants();
96 int oldCapacity = elements.length;
97 int newCapacity;
98 // Double size if small; else grow by 50%
99 int jump = (oldCapacity < 64) ? (oldCapacity + 2) : (oldCapacity >> 1);
100 if (jump < needed
101 || (newCapacity = (oldCapacity + jump)) - MAX_ARRAY_SIZE > 0)
102 newCapacity = newCapacity(needed, jump);
103 elements = Arrays.copyOf(elements, newCapacity);
104 if (oldCapacity - head < size) {
105 // wrap around; slide first leg forward to end of array
106 int newSpace = newCapacity - oldCapacity;
107 System.arraycopy(elements, head,
108 elements, head + newSpace,
109 oldCapacity - head);
110 Arrays.fill(elements, head, head + newSpace, null);
111 head += newSpace;
112 }
113 // checkInvariants();
114 }
115
116 /** Capacity calculation for edge conditions, especially overflow. */
117 private int newCapacity(int needed, int jump) {
118 int oldCapacity = elements.length;
119 int minCapacity;
120 if ((minCapacity = oldCapacity + needed) - MAX_ARRAY_SIZE > 0) {
121 if (minCapacity < 0)
122 throw new IllegalStateException("Sorry, deque too big");
123 return Integer.MAX_VALUE;
124 }
125 if (needed > jump)
126 return minCapacity;
127 return (oldCapacity + jump - MAX_ARRAY_SIZE < 0)
128 ? oldCapacity + jump
129 : MAX_ARRAY_SIZE;
130 }
131
132 /**
133 * Increases the internal storage of this collection, if necessary,
134 * to ensure that it can hold at least the given number of elements.
135 *
136 * @param minCapacity the desired minimum capacity
137 * @since TBD
138 */
139 /* public */ void ensureCapacity(int minCapacity) {
140 if (minCapacity > elements.length)
141 grow(minCapacity - elements.length);
142 // checkInvariants();
143 }
144
145 /**
146 * Minimizes the internal storage of this collection.
147 *
148 * @since TBD
149 */
150 /* public */ void trimToSize() {
151 if (size < elements.length) {
152 elements = toArray();
153 head = 0;
154 }
155 // checkInvariants();
156 }
157
158 /**
159 * Constructs an empty array deque with an initial capacity
160 * sufficient to hold 16 elements.
161 */
162 public ArrayDeque() {
163 elements = new Object[16];
164 }
165
166 /**
167 * Constructs an empty array deque with an initial capacity
168 * sufficient to hold the specified number of elements.
169 *
170 * @param numElements lower bound on initial capacity of the deque
171 */
172 public ArrayDeque(int numElements) {
173 elements = new Object[numElements];
174 }
175
176 /**
177 * Constructs a deque containing the elements of the specified
178 * collection, in the order they are returned by the collection's
179 * iterator. (The first element returned by the collection's
180 * iterator becomes the first element, or <i>front</i> of the
181 * deque.)
182 *
183 * @param c the collection whose elements are to be placed into the deque
184 * @throws NullPointerException if the specified collection is null
185 */
186 public ArrayDeque(Collection<? extends E> c) {
187 Object[] elements = c.toArray();
188 // defend against c.toArray (incorrectly) not returning Object[]
189 // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
190 if (elements.getClass() != Object[].class)
191 elements = Arrays.copyOf(elements, size, Object[].class);
192 for (Object obj : elements)
193 Objects.requireNonNull(obj);
194 size = elements.length;
195 this.elements = elements;
196 }
197
198 /**
199 * Increments i, mod modulus.
200 * Precondition and postcondition: 0 <= i < modulus.
201 */
202 static final int inc(int i, int modulus) {
203 if (++i == modulus) i = 0;
204 return i;
205 }
206
207 /**
208 * Decrements i, mod modulus.
209 * Precondition and postcondition: 0 <= i < modulus.
210 */
211 static final int dec(int i, int modulus) {
212 if (--i < 0) i += modulus;
213 return i;
214 }
215
216 /**
217 * Adds i and j, mod modulus.
218 * Precondition and postcondition: 0 <= i < modulus, 0 <= j <= modulus.
219 */
220 static final int add(int i, int j, int modulus) {
221 if ((i += j) - modulus >= 0) i -= modulus;
222 return i;
223 }
224
225 /**
226 * Returns the array index of the last element.
227 * May return invalid index -1 if there are no elements.
228 */
229 final int tail() {
230 return add(head, size - 1, elements.length);
231 }
232
233 /**
234 * Returns element at array index i.
235 */
236 @SuppressWarnings("unchecked")
237 final E elementAt(int i) {
238 return (E) elements[i];
239 }
240
241 /**
242 * A version of elementAt that checks for null elements.
243 * This check doesn't catch all possible comodifications,
244 * but does catch ones that corrupt traversal.
245 */
246 E checkedElementAt(Object[] elements, int i) {
247 @SuppressWarnings("unchecked") E e = (E) elements[i];
248 if (e == null)
249 throw new ConcurrentModificationException();
250 return e;
251 }
252
253 // The main insertion and extraction methods are addFirst,
254 // addLast, pollFirst, pollLast. The other methods are defined in
255 // terms of these.
256
257 /**
258 * Inserts the specified element at the front of this deque.
259 *
260 * @param e the element to add
261 * @throws NullPointerException if the specified element is null
262 */
263 public void addFirst(E e) {
264 // checkInvariants();
265 Objects.requireNonNull(e);
266 final Object[] elements;
267 final int capacity, s;
268 if ((s = size) == (capacity = (elements = this.elements).length))
269 addFirstSlowPath(e);
270 else
271 elements[head = dec(head, capacity)] = e;
272 size = s + 1;
273 // checkInvariants();
274 }
275
276 private void addFirstSlowPath(E e) {
277 grow(1);
278 final Object[] elements = this.elements;
279 elements[head = dec(head, elements.length)] = e;
280 }
281
282 /**
283 * Inserts the specified element at the end of this deque.
284 *
285 * <p>This method is equivalent to {@link #add}.
286 *
287 * @param e the element to add
288 * @throws NullPointerException if the specified element is null
289 */
290 public void addLast(E e) {
291 // checkInvariants();
292 Objects.requireNonNull(e);
293 final Object[] elements;
294 final int capacity, s;
295 if ((s = size) == (capacity = (elements = this.elements).length))
296 addLastSlowPath(e);
297 else
298 elements[add(head, s, capacity)] = e;
299 size = s + 1;
300 // checkInvariants();
301 }
302
303 private void addLastSlowPath(E e) {
304 grow(1);
305 final Object[] elements = this.elements;
306 elements[add(head, size, elements.length)] = e;
307 }
308
309 /**
310 * Adds all of the elements in the specified collection at the end
311 * of this deque, as if by calling {@link #addLast} on each one,
312 * in the order that they are returned by the collection's
313 * iterator.
314 *
315 * @param c the elements to be inserted into this deque
316 * @return {@code true} if this deque changed as a result of the call
317 * @throws NullPointerException if the specified collection or any
318 * of its elements are null
319 */
320 @Override
321 public boolean addAll(Collection<? extends E> c) {
322 // checkInvariants();
323 Object[] a, elements;
324 int newcomers, capacity, s = size;
325 if ((newcomers = (a = c.toArray()).length) == 0)
326 return false;
327 while ((capacity = (elements = this.elements).length) - s < newcomers)
328 grow(newcomers - (capacity - s));
329 int i = add(head, s, capacity);
330 for (Object x : a) {
331 Objects.requireNonNull(x);
332 elements[i] = x;
333 i = inc(i, capacity);
334 size++;
335 }
336 return true;
337 }
338
339 /**
340 * Inserts the specified element at the front of this deque.
341 *
342 * @param e the element to add
343 * @return {@code true} (as specified by {@link Deque#offerFirst})
344 * @throws NullPointerException if the specified element is null
345 */
346 public boolean offerFirst(E e) {
347 addFirst(e);
348 return true;
349 }
350
351 /**
352 * Inserts the specified element at the end of this deque.
353 *
354 * @param e the element to add
355 * @return {@code true} (as specified by {@link Deque#offerLast})
356 * @throws NullPointerException if the specified element is null
357 */
358 public boolean offerLast(E e) {
359 addLast(e);
360 return true;
361 }
362
363 /**
364 * @throws NoSuchElementException {@inheritDoc}
365 */
366 public E removeFirst() {
367 // checkInvariants();
368 E x = pollFirst();
369 if (x == null)
370 throw new NoSuchElementException();
371 return x;
372 }
373
374 /**
375 * @throws NoSuchElementException {@inheritDoc}
376 */
377 public E removeLast() {
378 // checkInvariants();
379 E x = pollLast();
380 if (x == null)
381 throw new NoSuchElementException();
382 return x;
383 }
384
385 public E pollFirst() {
386 // checkInvariants();
387 final int s, h;
388 if ((s = size) == 0)
389 return null;
390 final Object[] elements = this.elements;
391 @SuppressWarnings("unchecked") E e = (E) elements[h = head];
392 elements[h] = null;
393 head = inc(h, elements.length);
394 size = s - 1;
395 return e;
396 }
397
398 public E pollLast() {
399 // checkInvariants();
400 final int s, tail;
401 if ((s = size) == 0)
402 return null;
403 final Object[] elements = this.elements;
404 @SuppressWarnings("unchecked")
405 E e = (E) elements[tail = add(head, s - 1, elements.length)];
406 elements[tail] = null;
407 size = s - 1;
408 return e;
409 }
410
411 /**
412 * @throws NoSuchElementException {@inheritDoc}
413 */
414 public E getFirst() {
415 // checkInvariants();
416 if (size == 0) throw new NoSuchElementException();
417 return elementAt(head);
418 }
419
420 /**
421 * @throws NoSuchElementException {@inheritDoc}
422 */
423 public E getLast() {
424 // checkInvariants();
425 if (size == 0) throw new NoSuchElementException();
426 return elementAt(tail());
427 }
428
429 public E peekFirst() {
430 // checkInvariants();
431 return (size == 0) ? null : elementAt(head);
432 }
433
434 public E peekLast() {
435 // checkInvariants();
436 return (size == 0) ? null : elementAt(tail());
437 }
438
439 /**
440 * Removes the first occurrence of the specified element in this
441 * deque (when traversing the deque from head to tail).
442 * If the deque does not contain the element, it is unchanged.
443 * More formally, removes the first element {@code e} such that
444 * {@code o.equals(e)} (if such an element exists).
445 * Returns {@code true} if this deque contained the specified element
446 * (or equivalently, if this deque changed as a result of the call).
447 *
448 * @param o element to be removed from this deque, if present
449 * @return {@code true} if the deque contained the specified element
450 */
451 public boolean removeFirstOccurrence(Object o) {
452 // checkInvariants();
453 if (o != null) {
454 final Object[] elements = this.elements;
455 final int capacity = elements.length;
456 for (int k = size, i = head; --k >= 0; i = inc(i, capacity)) {
457 if (o.equals(elements[i])) {
458 delete(i);
459 return true;
460 }
461 }
462 }
463 return false;
464 }
465
466 /**
467 * Removes the last occurrence of the specified element in this
468 * deque (when traversing the deque from head to tail).
469 * If the deque does not contain the element, it is unchanged.
470 * More formally, removes the last element {@code e} such that
471 * {@code o.equals(e)} (if such an element exists).
472 * Returns {@code true} if this deque contained the specified element
473 * (or equivalently, if this deque changed as a result of the call).
474 *
475 * @param o element to be removed from this deque, if present
476 * @return {@code true} if the deque contained the specified element
477 */
478 public boolean removeLastOccurrence(Object o) {
479 if (o != null) {
480 final Object[] elements = this.elements;
481 final int capacity = elements.length;
482 for (int k = size, i = add(head, k - 1, capacity);
483 --k >= 0; i = dec(i, capacity)) {
484 if (o.equals(elements[i])) {
485 delete(i);
486 return true;
487 }
488 }
489 }
490 return false;
491 }
492
493 // *** Queue methods ***
494
495 /**
496 * Inserts the specified element at the end of this deque.
497 *
498 * <p>This method is equivalent to {@link #addLast}.
499 *
500 * @param e the element to add
501 * @return {@code true} (as specified by {@link Collection#add})
502 * @throws NullPointerException if the specified element is null
503 */
504 public boolean add(E e) {
505 addLast(e);
506 return true;
507 }
508
509 /**
510 * Inserts the specified element at the end of this deque.
511 *
512 * <p>This method is equivalent to {@link #offerLast}.
513 *
514 * @param e the element to add
515 * @return {@code true} (as specified by {@link Queue#offer})
516 * @throws NullPointerException if the specified element is null
517 */
518 public boolean offer(E e) {
519 return offerLast(e);
520 }
521
522 /**
523 * Retrieves and removes the head of the queue represented by this deque.
524 *
525 * This method differs from {@link #poll poll} only in that it throws an
526 * exception if this deque is empty.
527 *
528 * <p>This method is equivalent to {@link #removeFirst}.
529 *
530 * @return the head of the queue represented by this deque
531 * @throws NoSuchElementException {@inheritDoc}
532 */
533 public E remove() {
534 return removeFirst();
535 }
536
537 /**
538 * Retrieves and removes the head of the queue represented by this deque
539 * (in other words, the first element of this deque), or returns
540 * {@code null} if this deque is empty.
541 *
542 * <p>This method is equivalent to {@link #pollFirst}.
543 *
544 * @return the head of the queue represented by this deque, or
545 * {@code null} if this deque is empty
546 */
547 public E poll() {
548 return pollFirst();
549 }
550
551 /**
552 * Retrieves, but does not remove, the head of the queue represented by
553 * this deque. This method differs from {@link #peek peek} only in
554 * that it throws an exception if this deque is empty.
555 *
556 * <p>This method is equivalent to {@link #getFirst}.
557 *
558 * @return the head of the queue represented by this deque
559 * @throws NoSuchElementException {@inheritDoc}
560 */
561 public E element() {
562 return getFirst();
563 }
564
565 /**
566 * Retrieves, but does not remove, the head of the queue represented by
567 * this deque, or returns {@code null} if this deque is empty.
568 *
569 * <p>This method is equivalent to {@link #peekFirst}.
570 *
571 * @return the head of the queue represented by this deque, or
572 * {@code null} if this deque is empty
573 */
574 public E peek() {
575 return peekFirst();
576 }
577
578 // *** Stack methods ***
579
580 /**
581 * Pushes an element onto the stack represented by this deque. In other
582 * words, inserts the element at the front of this deque.
583 *
584 * <p>This method is equivalent to {@link #addFirst}.
585 *
586 * @param e the element to push
587 * @throws NullPointerException if the specified element is null
588 */
589 public void push(E e) {
590 addFirst(e);
591 }
592
593 /**
594 * Pops an element from the stack represented by this deque. In other
595 * words, removes and returns the first element of this deque.
596 *
597 * <p>This method is equivalent to {@link #removeFirst()}.
598 *
599 * @return the element at the front of this deque (which is the top
600 * of the stack represented by this deque)
601 * @throws NoSuchElementException {@inheritDoc}
602 */
603 public E pop() {
604 return removeFirst();
605 }
606
607 /**
608 * Removes the element at the specified position in the elements array.
609 * This can result in forward or backwards motion of array elements.
610 * We optimize for least element motion.
611 *
612 * <p>This method is called delete rather than remove to emphasize
613 * that its semantics differ from those of {@link List#remove(int)}.
614 *
615 * @return true if elements moved backwards
616 */
617 boolean delete(int i) {
618 // checkInvariants();
619 final Object[] elements = this.elements;
620 final int capacity = elements.length;
621 final int h = head;
622 int front; // number of elements before to-be-deleted elt
623 if ((front = i - h) < 0) front += capacity;
624 final int back = size - front - 1; // number of elements after
625 if (front < back) {
626 // move front elements forwards
627 if (h <= i) {
628 System.arraycopy(elements, h, elements, h + 1, front);
629 } else { // Wrap around
630 System.arraycopy(elements, 0, elements, 1, i);
631 elements[0] = elements[capacity - 1];
632 System.arraycopy(elements, h, elements, h + 1, front - (i + 1));
633 }
634 elements[h] = null;
635 head = inc(h, capacity);
636 size--;
637 // checkInvariants();
638 return false;
639 } else {
640 // move back elements backwards
641 int tail = tail();
642 if (i <= tail) {
643 System.arraycopy(elements, i + 1, elements, i, back);
644 } else { // Wrap around
645 int firstLeg = capacity - (i + 1);
646 System.arraycopy(elements, i + 1, elements, i, firstLeg);
647 elements[capacity - 1] = elements[0];
648 System.arraycopy(elements, 1, elements, 0, back - firstLeg - 1);
649 }
650 elements[tail] = null;
651 size--;
652 // checkInvariants();
653 return true;
654 }
655 }
656
657 // *** Collection Methods ***
658
659 /**
660 * Returns the number of elements in this deque.
661 *
662 * @return the number of elements in this deque
663 */
664 public int size() {
665 return size;
666 }
667
668 /**
669 * Returns {@code true} if this deque contains no elements.
670 *
671 * @return {@code true} if this deque contains no elements
672 */
673 public boolean isEmpty() {
674 return size == 0;
675 }
676
677 /**
678 * Returns an iterator over the elements in this deque. The elements
679 * will be ordered from first (head) to last (tail). This is the same
680 * order that elements would be dequeued (via successive calls to
681 * {@link #remove} or popped (via successive calls to {@link #pop}).
682 *
683 * @return an iterator over the elements in this deque
684 */
685 public Iterator<E> iterator() {
686 return new DeqIterator();
687 }
688
689 public Iterator<E> descendingIterator() {
690 return new DescendingIterator();
691 }
692
693 private class DeqIterator implements Iterator<E> {
694 /** Index of element to be returned by subsequent call to next. */
695 int cursor;
696
697 /** Number of elements yet to be returned. */
698 int remaining = size;
699
700 /**
701 * Index of element returned by most recent call to next.
702 * Reset to -1 if element is deleted by a call to remove.
703 */
704 int lastRet = -1;
705
706 DeqIterator() { cursor = head; }
707
708 public final boolean hasNext() {
709 return remaining > 0;
710 }
711
712 public E next() {
713 if (remaining == 0)
714 throw new NoSuchElementException();
715 E e = checkedElementAt(elements, cursor);
716 lastRet = cursor;
717 cursor = inc(cursor, elements.length);
718 remaining--;
719 return e;
720 }
721
722 void postDelete(boolean leftShifted) {
723 if (leftShifted)
724 cursor = dec(cursor, elements.length); // undo inc in next
725 }
726
727 public final void remove() {
728 if (lastRet < 0)
729 throw new IllegalStateException();
730 postDelete(delete(lastRet));
731 lastRet = -1;
732 }
733
734 public void forEachRemaining(Consumer<? super E> action) {
735 Objects.requireNonNull(action);
736 final Object[] elements = ArrayDeque.this.elements;
737 final int capacity = elements.length;
738 int k = remaining;
739 remaining = 0;
740 for (int i = cursor; --k >= 0; i = inc(i, capacity))
741 action.accept(checkedElementAt(elements, i));
742 }
743 }
744
745 private class DescendingIterator extends DeqIterator {
746 DescendingIterator() { cursor = tail(); }
747
748 public final E next() {
749 if (remaining == 0)
750 throw new NoSuchElementException();
751 E e = checkedElementAt(elements, cursor);
752 lastRet = cursor;
753 cursor = dec(cursor, elements.length);
754 remaining--;
755 return e;
756 }
757
758 void postDelete(boolean leftShifted) {
759 if (!leftShifted)
760 cursor = inc(cursor, elements.length); // undo dec in next
761 }
762
763 public final void forEachRemaining(Consumer<? super E> action) {
764 Objects.requireNonNull(action);
765 final Object[] elements = ArrayDeque.this.elements;
766 final int capacity = elements.length;
767 int k = remaining;
768 remaining = 0;
769 for (int i = cursor; --k >= 0; i = dec(i, capacity))
770 action.accept(checkedElementAt(elements, i));
771 }
772 }
773
774 /**
775 * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
776 * and <em>fail-fast</em> {@link Spliterator} over the elements in this
777 * deque.
778 *
779 * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
780 * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
781 * {@link Spliterator#NONNULL}. Overriding implementations should document
782 * the reporting of additional characteristic values.
783 *
784 * @return a {@code Spliterator} over the elements in this deque
785 * @since 1.8
786 */
787 public Spliterator<E> spliterator() {
788 return new ArrayDequeSpliterator();
789 }
790
791 final class ArrayDequeSpliterator implements Spliterator<E> {
792 private int cursor;
793 private int remaining; // -1 until late-binding first use
794
795 /** Constructs late-binding spliterator over all elements. */
796 ArrayDequeSpliterator() {
797 this.remaining = -1;
798 }
799
800 /** Constructs spliterator over the given slice. */
801 ArrayDequeSpliterator(int cursor, int count) {
802 this.cursor = cursor;
803 this.remaining = count;
804 }
805
806 /** Ensures late-binding initialization; then returns remaining. */
807 private int remaining() {
808 if (remaining < 0) {
809 cursor = head;
810 remaining = size;
811 }
812 return remaining;
813 }
814
815 public ArrayDequeSpliterator trySplit() {
816 final int mid;
817 if ((mid = remaining() >> 1) > 0) {
818 int oldCursor = cursor;
819 cursor = add(cursor, mid, elements.length);
820 remaining -= mid;
821 return new ArrayDequeSpliterator(oldCursor, mid);
822 }
823 return null;
824 }
825
826 public void forEachRemaining(Consumer<? super E> action) {
827 Objects.requireNonNull(action);
828 final Object[] elements = ArrayDeque.this.elements;
829 final int capacity = elements.length;
830 int k = remaining();
831 remaining = 0;
832 for (int i = cursor; --k >= 0; i = inc(i, capacity))
833 action.accept(checkedElementAt(elements, i));
834 }
835
836 public boolean tryAdvance(Consumer<? super E> action) {
837 Objects.requireNonNull(action);
838 if (remaining() == 0)
839 return false;
840 action.accept(checkedElementAt(elements, cursor));
841 cursor = inc(cursor, elements.length);
842 remaining--;
843 return true;
844 }
845
846 public long estimateSize() {
847 return remaining();
848 }
849
850 public int characteristics() {
851 return Spliterator.NONNULL
852 | Spliterator.ORDERED
853 | Spliterator.SIZED
854 | Spliterator.SUBSIZED;
855 }
856 }
857
858 @Override
859 public void forEach(Consumer<? super E> action) {
860 // checkInvariants();
861 Objects.requireNonNull(action);
862 final Object[] elements = this.elements;
863 final int capacity = elements.length;
864 for (int k = size, i = head; --k >= 0; i = inc(i, capacity))
865 action.accept(elementAt(i));
866 // checkInvariants();
867 }
868
869 /**
870 * Replaces each element of this deque with the result of applying the
871 * operator to that element, as specified by {@link List#replaceAll}.
872 *
873 * @param operator the operator to apply to each element
874 * @since TBD
875 */
876 /* public */ void replaceAll(UnaryOperator<E> operator) {
877 Objects.requireNonNull(operator);
878 final Object[] elements = this.elements;
879 final int capacity = elements.length;
880 for (int k = size, i = head; --k >= 0; i = inc(i, capacity))
881 elements[i] = operator.apply(elementAt(i));
882 // checkInvariants();
883 }
884
885 /**
886 * @throws NullPointerException {@inheritDoc}
887 */
888 @Override
889 public boolean removeIf(Predicate<? super E> filter) {
890 Objects.requireNonNull(filter);
891 return bulkRemove(filter);
892 }
893
894 /**
895 * @throws NullPointerException {@inheritDoc}
896 */
897 @Override
898 public boolean removeAll(Collection<?> c) {
899 Objects.requireNonNull(c);
900 return bulkRemove(e -> c.contains(e));
901 }
902
903 /**
904 * @throws NullPointerException {@inheritDoc}
905 */
906 @Override
907 public boolean retainAll(Collection<?> c) {
908 Objects.requireNonNull(c);
909 return bulkRemove(e -> !c.contains(e));
910 }
911
912 /** Implementation of bulk remove methods. */
913 private boolean bulkRemove(Predicate<? super E> filter) {
914 // checkInvariants();
915 final Object[] elements = this.elements;
916 final int capacity = elements.length;
917 int i = head, j = i, remaining = size, deleted = 0;
918 try {
919 for (; remaining > 0; remaining--, i = inc(i, capacity)) {
920 @SuppressWarnings("unchecked") E e = (E) elements[i];
921 if (filter.test(e))
922 deleted++;
923 else {
924 if (j != i)
925 elements[j] = e;
926 j = inc(j, capacity);
927 }
928 }
929 return deleted > 0;
930 } catch (Throwable ex) {
931 if (deleted > 0)
932 for (; remaining > 0;
933 remaining--, i = inc(i, capacity), j = inc(j, capacity))
934 elements[j] = elements[i];
935 throw ex;
936 } finally {
937 size -= deleted;
938 for (; --deleted >= 0; j = inc(j, capacity))
939 elements[j] = null;
940 // checkInvariants();
941 }
942 }
943
944 /**
945 * Returns {@code true} if this deque contains the specified element.
946 * More formally, returns {@code true} if and only if this deque contains
947 * at least one element {@code e} such that {@code o.equals(e)}.
948 *
949 * @param o object to be checked for containment in this deque
950 * @return {@code true} if this deque contains the specified element
951 */
952 public boolean contains(Object o) {
953 if (o != null) {
954 final Object[] elements = this.elements;
955 final int capacity = elements.length;
956 for (int k = size, i = head; --k >= 0; i = inc(i, capacity))
957 if (o.equals(elements[i]))
958 return true;
959 }
960 return false;
961 }
962
963 /**
964 * Removes a single instance of the specified element from this deque.
965 * If the deque does not contain the element, it is unchanged.
966 * More formally, removes the first element {@code e} such that
967 * {@code o.equals(e)} (if such an element exists).
968 * Returns {@code true} if this deque contained the specified element
969 * (or equivalently, if this deque changed as a result of the call).
970 *
971 * <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}.
972 *
973 * @param o element to be removed from this deque, if present
974 * @return {@code true} if this deque contained the specified element
975 */
976 public boolean remove(Object o) {
977 return removeFirstOccurrence(o);
978 }
979
980 /**
981 * Removes all of the elements from this deque.
982 * The deque will be empty after this call returns.
983 */
984 public void clear() {
985 final Object[] elements = this.elements;
986 final int capacity = elements.length;
987 final int h = this.head;
988 final int s = size;
989 if (capacity - h >= s)
990 Arrays.fill(elements, h, h + s, null);
991 else {
992 Arrays.fill(elements, h, capacity, null);
993 Arrays.fill(elements, 0, s - capacity + h, null);
994 }
995 size = head = 0;
996 // checkInvariants();
997 }
998
999 /**
1000 * Returns an array containing all of the elements in this deque
1001 * in proper sequence (from first to last element).
1002 *
1003 * <p>The returned array will be "safe" in that no references to it are
1004 * maintained by this deque. (In other words, this method must allocate
1005 * a new array). The caller is thus free to modify the returned array.
1006 *
1007 * <p>This method acts as bridge between array-based and collection-based
1008 * APIs.
1009 *
1010 * @return an array containing all of the elements in this deque
1011 */
1012 public Object[] toArray() {
1013 final int head = this.head;
1014 final int firstLeg;
1015 Object[] a = Arrays.copyOfRange(elements, head, head + size);
1016 if ((firstLeg = elements.length - head) < size)
1017 System.arraycopy(elements, 0, a, firstLeg, size - firstLeg);
1018 return a;
1019 }
1020
1021 /**
1022 * Returns an array containing all of the elements in this deque in
1023 * proper sequence (from first to last element); the runtime type of the
1024 * returned array is that of the specified array. If the deque fits in
1025 * the specified array, it is returned therein. Otherwise, a new array
1026 * is allocated with the runtime type of the specified array and the
1027 * size of this deque.
1028 *
1029 * <p>If this deque fits in the specified array with room to spare
1030 * (i.e., the array has more elements than this deque), the element in
1031 * the array immediately following the end of the deque is set to
1032 * {@code null}.
1033 *
1034 * <p>Like the {@link #toArray()} method, this method acts as bridge between
1035 * array-based and collection-based APIs. Further, this method allows
1036 * precise control over the runtime type of the output array, and may,
1037 * under certain circumstances, be used to save allocation costs.
1038 *
1039 * <p>Suppose {@code x} is a deque known to contain only strings.
1040 * The following code can be used to dump the deque into a newly
1041 * allocated array of {@code String}:
1042 *
1043 * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
1044 *
1045 * Note that {@code toArray(new Object[0])} is identical in function to
1046 * {@code toArray()}.
1047 *
1048 * @param a the array into which the elements of the deque are to
1049 * be stored, if it is big enough; otherwise, a new array of the
1050 * same runtime type is allocated for this purpose
1051 * @return an array containing all of the elements in this deque
1052 * @throws ArrayStoreException if the runtime type of the specified array
1053 * is not a supertype of the runtime type of every element in
1054 * this deque
1055 * @throws NullPointerException if the specified array is null
1056 */
1057 @SuppressWarnings("unchecked")
1058 public <T> T[] toArray(T[] a) {
1059 final Object[] elements = this.elements;
1060 final int head = this.head;
1061 final int firstLeg;
1062 boolean wrap = (firstLeg = elements.length - head) < size;
1063 if (size > a.length) {
1064 a = (T[]) Arrays.copyOfRange(elements, head, head + size,
1065 a.getClass());
1066 } else {
1067 System.arraycopy(elements, head, a, 0, wrap ? firstLeg : size);
1068 if (size < a.length)
1069 a[size] = null;
1070 }
1071 if (wrap)
1072 System.arraycopy(elements, 0, a, firstLeg, size - firstLeg);
1073 return a;
1074 }
1075
1076 // *** Object methods ***
1077
1078 /**
1079 * Returns a copy of this deque.
1080 *
1081 * @return a copy of this deque
1082 */
1083 public ArrayDeque<E> clone() {
1084 try {
1085 @SuppressWarnings("unchecked")
1086 ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
1087 result.elements = Arrays.copyOf(elements, elements.length);
1088 return result;
1089 } catch (CloneNotSupportedException e) {
1090 throw new AssertionError();
1091 }
1092 }
1093
1094 private static final long serialVersionUID = 2340985798034038923L;
1095
1096 /**
1097 * Saves this deque to a stream (that is, serializes it).
1098 *
1099 * @param s the stream
1100 * @throws java.io.IOException if an I/O error occurs
1101 * @serialData The current size ({@code int}) of the deque,
1102 * followed by all of its elements (each an object reference) in
1103 * first-to-last order.
1104 */
1105 private void writeObject(java.io.ObjectOutputStream s)
1106 throws java.io.IOException {
1107 s.defaultWriteObject();
1108
1109 // Write out size
1110 s.writeInt(size);
1111
1112 // Write out elements in order.
1113 final Object[] elements = this.elements;
1114 final int capacity = elements.length;
1115 for (int k = size, i = head; --k >= 0; i = inc(i, capacity))
1116 s.writeObject(elements[i]);
1117 }
1118
1119 /**
1120 * Reconstitutes this deque from a stream (that is, deserializes it).
1121 * @param s the stream
1122 * @throws ClassNotFoundException if the class of a serialized object
1123 * could not be found
1124 * @throws java.io.IOException if an I/O error occurs
1125 */
1126 private void readObject(java.io.ObjectInputStream s)
1127 throws java.io.IOException, ClassNotFoundException {
1128 s.defaultReadObject();
1129
1130 // Read in size and allocate array
1131 elements = new Object[size = s.readInt()];
1132
1133 // Read in all elements in the proper order.
1134 for (int i = 0; i < size; i++)
1135 elements[i] = s.readObject();
1136 }
1137
1138 /** debugging */
1139 private void checkInvariants() {
1140 try {
1141 int capacity = elements.length;
1142 assert size >= 0 && size <= capacity;
1143 assert head >= 0 && ((capacity == 0 && head == 0 && size == 0)
1144 || head < capacity);
1145 assert size == 0
1146 || (elements[head] != null && elements[tail()] != null);
1147 assert size == capacity
1148 || (elements[dec(head, capacity)] == null
1149 && elements[inc(tail(), capacity)] == null);
1150 } catch (Throwable t) {
1151 System.err.printf("head=%d size=%d capacity=%d%n",
1152 head, size, elements.length);
1153 System.err.printf("elements=%s%n",
1154 Arrays.toString(elements));
1155 throw t;
1156 }
1157 }
1158
1159 }