ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/ArrayDeque.java
Revision: 1.76
Committed: Mon Oct 17 23:49:00 2016 UTC (7 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.75: +22 -8 lines
Log Message:
ArrayDeque#spliterator is late-binding

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 9
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 9
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 * Returns the array index of the last element.
200 * May return invalid index -1 if there are no elements.
201 */
202 final int tail() {
203 return add(head, size - 1, elements.length);
204 }
205
206 /**
207 * Adds i and j, mod modulus.
208 * Precondition and postcondition: 0 <= i < modulus, 0 <= j <= modulus.
209 */
210 static final int add(int i, int j, int modulus) {
211 if ((i += j) - modulus >= 0) i -= modulus;
212 return i;
213 }
214
215 /**
216 * Increments i, mod modulus.
217 * Precondition and postcondition: 0 <= i < modulus.
218 */
219 static final int inc(int i, int modulus) {
220 if (++i == modulus) i = 0;
221 return i;
222 }
223
224 /**
225 * Decrements i, mod modulus.
226 * Precondition and postcondition: 0 <= i < modulus.
227 */
228 static final int dec(int i, int modulus) {
229 if (--i < 0) i += modulus;
230 return i;
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 Object[] elements;
267 int capacity, s = size;
268 while (s == (capacity = (elements = this.elements).length))
269 grow(1);
270 elements[head = dec(head, capacity)] = e;
271 size = s + 1;
272 }
273
274 /**
275 * Inserts the specified element at the end of this deque.
276 *
277 * <p>This method is equivalent to {@link #add}.
278 *
279 * @param e the element to add
280 * @throws NullPointerException if the specified element is null
281 */
282 public void addLast(E e) {
283 // checkInvariants();
284 Objects.requireNonNull(e);
285 Object[] elements;
286 int capacity, s = size;
287 while (s == (capacity = (elements = this.elements).length))
288 grow(1);
289 elements[add(head, s, capacity)] = e;
290 size = s + 1;
291 }
292
293 /**
294 * Adds all of the elements in the specified collection at the end
295 * of this deque, as if by calling {@link #addLast} on each one,
296 * in the order that they are returned by the collection's
297 * iterator.
298 *
299 * @param c the elements to be inserted into this deque
300 * @return {@code true} if this deque changed as a result of the call
301 * @throws NullPointerException if the specified collection or any
302 * of its elements are null
303 */
304 @Override
305 public boolean addAll(Collection<? extends E> c) {
306 // checkInvariants();
307 Object[] a, elements;
308 int len, capacity, s = size;
309 if ((len = (a = c.toArray()).length) == 0)
310 return false;
311 while ((capacity = (elements = this.elements).length) - s < len)
312 grow(len - (capacity - s));
313 int i = add(head, s, capacity);
314 for (Object x : a) {
315 Objects.requireNonNull(x);
316 elements[i] = x;
317 i = inc(i, capacity);
318 size++;
319 }
320 return true;
321 }
322
323 /**
324 * Inserts the specified element at the front of this deque.
325 *
326 * @param e the element to add
327 * @return {@code true} (as specified by {@link Deque#offerFirst})
328 * @throws NullPointerException if the specified element is null
329 */
330 public boolean offerFirst(E e) {
331 addFirst(e);
332 return true;
333 }
334
335 /**
336 * Inserts the specified element at the end of this deque.
337 *
338 * @param e the element to add
339 * @return {@code true} (as specified by {@link Deque#offerLast})
340 * @throws NullPointerException if the specified element is null
341 */
342 public boolean offerLast(E e) {
343 addLast(e);
344 return true;
345 }
346
347 /**
348 * @throws NoSuchElementException {@inheritDoc}
349 */
350 public E removeFirst() {
351 // checkInvariants();
352 E x = pollFirst();
353 if (x == null)
354 throw new NoSuchElementException();
355 return x;
356 }
357
358 /**
359 * @throws NoSuchElementException {@inheritDoc}
360 */
361 public E removeLast() {
362 // checkInvariants();
363 E x = pollLast();
364 if (x == null)
365 throw new NoSuchElementException();
366 return x;
367 }
368
369 public E pollFirst() {
370 // checkInvariants();
371 final int s, h;
372 if ((s = size) == 0)
373 return null;
374 final Object[] elements = this.elements;
375 @SuppressWarnings("unchecked") E e = (E) elements[h = head];
376 elements[h] = null;
377 head = inc(h, elements.length);
378 size = s - 1;
379 return e;
380 }
381
382 public E pollLast() {
383 // checkInvariants();
384 final int s, tail;
385 if ((s = size) == 0)
386 return null;
387 final Object[] elements = this.elements;
388 @SuppressWarnings("unchecked")
389 E e = (E) elements[tail = add(head, s - 1, elements.length)];
390 elements[tail] = null;
391 size = s - 1;
392 return e;
393 }
394
395 /**
396 * @throws NoSuchElementException {@inheritDoc}
397 */
398 public E getFirst() {
399 // checkInvariants();
400 if (size == 0) throw new NoSuchElementException();
401 return elementAt(head);
402 }
403
404 /**
405 * @throws NoSuchElementException {@inheritDoc}
406 */
407 public E getLast() {
408 // checkInvariants();
409 if (size == 0) throw new NoSuchElementException();
410 return elementAt(tail());
411 }
412
413 public E peekFirst() {
414 // checkInvariants();
415 return (size == 0) ? null : elementAt(head);
416 }
417
418 public E peekLast() {
419 // checkInvariants();
420 return (size == 0) ? null : elementAt(tail());
421 }
422
423 /**
424 * Removes the first occurrence of the specified element in this
425 * deque (when traversing the deque from head to tail).
426 * If the deque does not contain the element, it is unchanged.
427 * More formally, removes the first element {@code e} such that
428 * {@code o.equals(e)} (if such an element exists).
429 * Returns {@code true} if this deque contained the specified element
430 * (or equivalently, if this deque changed as a result of the call).
431 *
432 * @param o element to be removed from this deque, if present
433 * @return {@code true} if the deque contained the specified element
434 */
435 public boolean removeFirstOccurrence(Object o) {
436 // checkInvariants();
437 if (o != null) {
438 final Object[] elements = this.elements;
439 final int capacity = elements.length;
440 for (int k = size, i = head; --k >= 0; i = inc(i, capacity)) {
441 if (o.equals(elements[i])) {
442 delete(i);
443 return true;
444 }
445 }
446 }
447 return false;
448 }
449
450 /**
451 * Removes the last occurrence of the specified element in this
452 * deque (when traversing the deque from head to tail).
453 * If the deque does not contain the element, it is unchanged.
454 * More formally, removes the last element {@code e} such that
455 * {@code o.equals(e)} (if such an element exists).
456 * Returns {@code true} if this deque contained the specified element
457 * (or equivalently, if this deque changed as a result of the call).
458 *
459 * @param o element to be removed from this deque, if present
460 * @return {@code true} if the deque contained the specified element
461 */
462 public boolean removeLastOccurrence(Object o) {
463 if (o != null) {
464 final Object[] elements = this.elements;
465 final int capacity = elements.length;
466 for (int k = size, i = add(head, k - 1, capacity);
467 --k >= 0; i = dec(i, capacity)) {
468 if (o.equals(elements[i])) {
469 delete(i);
470 return true;
471 }
472 }
473 }
474 return false;
475 }
476
477 // *** Queue methods ***
478
479 /**
480 * Inserts the specified element at the end of this deque.
481 *
482 * <p>This method is equivalent to {@link #addLast}.
483 *
484 * @param e the element to add
485 * @return {@code true} (as specified by {@link Collection#add})
486 * @throws NullPointerException if the specified element is null
487 */
488 public boolean add(E e) {
489 addLast(e);
490 return true;
491 }
492
493 /**
494 * Inserts the specified element at the end of this deque.
495 *
496 * <p>This method is equivalent to {@link #offerLast}.
497 *
498 * @param e the element to add
499 * @return {@code true} (as specified by {@link Queue#offer})
500 * @throws NullPointerException if the specified element is null
501 */
502 public boolean offer(E e) {
503 return offerLast(e);
504 }
505
506 /**
507 * Retrieves and removes the head of the queue represented by this deque.
508 *
509 * This method differs from {@link #poll poll} only in that it throws an
510 * exception if this deque is empty.
511 *
512 * <p>This method is equivalent to {@link #removeFirst}.
513 *
514 * @return the head of the queue represented by this deque
515 * @throws NoSuchElementException {@inheritDoc}
516 */
517 public E remove() {
518 return removeFirst();
519 }
520
521 /**
522 * Retrieves and removes the head of the queue represented by this deque
523 * (in other words, the first element of this deque), or returns
524 * {@code null} if this deque is empty.
525 *
526 * <p>This method is equivalent to {@link #pollFirst}.
527 *
528 * @return the head of the queue represented by this deque, or
529 * {@code null} if this deque is empty
530 */
531 public E poll() {
532 return pollFirst();
533 }
534
535 /**
536 * Retrieves, but does not remove, the head of the queue represented by
537 * this deque. This method differs from {@link #peek peek} only in
538 * that it throws an exception if this deque is empty.
539 *
540 * <p>This method is equivalent to {@link #getFirst}.
541 *
542 * @return the head of the queue represented by this deque
543 * @throws NoSuchElementException {@inheritDoc}
544 */
545 public E element() {
546 return getFirst();
547 }
548
549 /**
550 * Retrieves, but does not remove, the head of the queue represented by
551 * this deque, or returns {@code null} if this deque is empty.
552 *
553 * <p>This method is equivalent to {@link #peekFirst}.
554 *
555 * @return the head of the queue represented by this deque, or
556 * {@code null} if this deque is empty
557 */
558 public E peek() {
559 return peekFirst();
560 }
561
562 // *** Stack methods ***
563
564 /**
565 * Pushes an element onto the stack represented by this deque. In other
566 * words, inserts the element at the front of this deque.
567 *
568 * <p>This method is equivalent to {@link #addFirst}.
569 *
570 * @param e the element to push
571 * @throws NullPointerException if the specified element is null
572 */
573 public void push(E e) {
574 addFirst(e);
575 }
576
577 /**
578 * Pops an element from the stack represented by this deque. In other
579 * words, removes and returns the first element of this deque.
580 *
581 * <p>This method is equivalent to {@link #removeFirst()}.
582 *
583 * @return the element at the front of this deque (which is the top
584 * of the stack represented by this deque)
585 * @throws NoSuchElementException {@inheritDoc}
586 */
587 public E pop() {
588 return removeFirst();
589 }
590
591 /**
592 * Removes the element at the specified position in the elements array.
593 * This can result in forward or backwards motion of array elements.
594 * We optimize for least element motion.
595 *
596 * <p>This method is called delete rather than remove to emphasize
597 * that its semantics differ from those of {@link List#remove(int)}.
598 *
599 * @return true if elements moved backwards
600 */
601 boolean delete(int i) {
602 // checkInvariants();
603 final Object[] elements = this.elements;
604 final int capacity = elements.length;
605 final int h = head;
606 int front; // number of elements before to-be-deleted elt
607 if ((front = i - h) < 0) front += capacity;
608 final int back = size - front - 1; // number of elements after
609 if (front < back) {
610 // move front elements forwards
611 if (h <= i) {
612 System.arraycopy(elements, h, elements, h + 1, front);
613 } else { // Wrap around
614 System.arraycopy(elements, 0, elements, 1, i);
615 elements[0] = elements[capacity - 1];
616 System.arraycopy(elements, h, elements, h + 1, front - (i + 1));
617 }
618 elements[h] = null;
619 head = inc(h, capacity);
620 size--;
621 // checkInvariants();
622 return false;
623 } else {
624 // move back elements backwards
625 int tail = tail();
626 if (i <= tail) {
627 System.arraycopy(elements, i + 1, elements, i, back);
628 } else { // Wrap around
629 int firstLeg = capacity - (i + 1);
630 System.arraycopy(elements, i + 1, elements, i, firstLeg);
631 elements[capacity - 1] = elements[0];
632 System.arraycopy(elements, 1, elements, 0, back - firstLeg - 1);
633 }
634 elements[tail] = null;
635 size--;
636 // checkInvariants();
637 return true;
638 }
639 }
640
641 // *** Collection Methods ***
642
643 /**
644 * Returns the number of elements in this deque.
645 *
646 * @return the number of elements in this deque
647 */
648 public int size() {
649 return size;
650 }
651
652 /**
653 * Returns {@code true} if this deque contains no elements.
654 *
655 * @return {@code true} if this deque contains no elements
656 */
657 public boolean isEmpty() {
658 return size == 0;
659 }
660
661 /**
662 * Returns an iterator over the elements in this deque. The elements
663 * will be ordered from first (head) to last (tail). This is the same
664 * order that elements would be dequeued (via successive calls to
665 * {@link #remove} or popped (via successive calls to {@link #pop}).
666 *
667 * @return an iterator over the elements in this deque
668 */
669 public Iterator<E> iterator() {
670 return new DeqIterator();
671 }
672
673 public Iterator<E> descendingIterator() {
674 return new DescendingIterator();
675 }
676
677 private class DeqIterator implements Iterator<E> {
678 /** Index of element to be returned by subsequent call to next. */
679 int cursor;
680
681 /** Number of elements yet to be returned. */
682 int remaining = size;
683
684 /**
685 * Index of element returned by most recent call to next.
686 * Reset to -1 if element is deleted by a call to remove.
687 */
688 int lastRet = -1;
689
690 DeqIterator() { cursor = head; }
691
692 void doAdvance() {
693 cursor = inc(cursor, elements.length);
694 }
695
696 void doRemove() {
697 if (delete(lastRet))
698 // if left-shifted, undo advance in next()
699 cursor = dec(cursor, elements.length);
700 }
701
702 public final boolean hasNext() {
703 return remaining > 0;
704 }
705
706 public final E next() {
707 if (remaining == 0)
708 throw new NoSuchElementException();
709 E e = checkedElementAt(elements, cursor);
710 lastRet = cursor;
711 doAdvance();
712 remaining--;
713 return e;
714 }
715
716 public final void remove() {
717 if (lastRet < 0)
718 throw new IllegalStateException();
719 doRemove();
720 lastRet = -1;
721 }
722
723 public final void forEachRemaining(Consumer<? super E> action) {
724 Objects.requireNonNull(action);
725 final Object[] elements = ArrayDeque.this.elements;
726 final int capacity = elements.length;
727 for (; remaining > 0; remaining--) {
728 action.accept(checkedElementAt(elements, cursor));
729 doAdvance();
730 }
731 }
732 }
733
734 private class DescendingIterator extends DeqIterator {
735 DescendingIterator() { cursor = tail(); }
736
737 @Override void doAdvance() {
738 cursor = dec(cursor, elements.length);
739 }
740
741 @Override void doRemove() {
742 if (!delete(lastRet))
743 // if right-shifted, undo advance in next
744 cursor = inc(cursor, elements.length);
745 }
746 }
747
748 /**
749 * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
750 * and <em>fail-fast</em> {@link Spliterator} over the elements in this
751 * deque.
752 *
753 * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
754 * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
755 * {@link Spliterator#NONNULL}. Overriding implementations should document
756 * the reporting of additional characteristic values.
757 *
758 * @return a {@code Spliterator} over the elements in this deque
759 * @since 1.8
760 */
761 public Spliterator<E> spliterator() {
762 return new ArrayDequeSpliterator();
763 }
764
765 final class ArrayDequeSpliterator implements Spliterator<E> {
766 private int cursor;
767 private int remaining; // -1 until late-binding first use
768
769 /** Constructs late-binding spliterator over all elements. */
770 ArrayDequeSpliterator() {
771 this.remaining = -1;
772 }
773
774 /** Constructs spliterator over the given slice. */
775 ArrayDequeSpliterator(int cursor, int count) {
776 this.cursor = cursor;
777 this.remaining = count;
778 }
779
780 /** Ensures late-binding initialization; then returns remaining. */
781 private int remaining() {
782 if (remaining < 0) {
783 cursor = head;
784 remaining = size;
785 }
786 return remaining;
787 }
788
789 public ArrayDequeSpliterator trySplit() {
790 if (remaining() > 1) {
791 int mid = remaining >> 1;
792 int oldCursor = cursor;
793 cursor = add(cursor, mid, elements.length);
794 remaining -= mid;
795 return new ArrayDequeSpliterator(oldCursor, mid);
796 }
797 return null;
798 }
799
800 public void forEachRemaining(Consumer<? super E> action) {
801 Objects.requireNonNull(action);
802 final Object[] elements = ArrayDeque.this.elements;
803 final int capacity = elements.length;
804 remaining(); // for the initialization side-effect
805 for (; remaining > 0; cursor = inc(cursor, capacity), remaining--)
806 action.accept(checkedElementAt(elements, cursor));
807 }
808
809 public boolean tryAdvance(Consumer<? super E> action) {
810 Objects.requireNonNull(action);
811 if (remaining() == 0)
812 return false;
813 action.accept(checkedElementAt(elements, cursor));
814 cursor = inc(cursor, elements.length);
815 remaining--;
816 return true;
817 }
818
819 public long estimateSize() {
820 return remaining();
821 }
822
823 public int characteristics() {
824 return Spliterator.NONNULL
825 | Spliterator.ORDERED
826 | Spliterator.SIZED
827 | Spliterator.SUBSIZED;
828 }
829 }
830
831 @Override
832 public void forEach(Consumer<? super E> action) {
833 // checkInvariants();
834 Objects.requireNonNull(action);
835 final Object[] elements = this.elements;
836 final int capacity = elements.length;
837 for (int k = size, i = head; --k >= 0; i = inc(i, capacity))
838 action.accept(elementAt(i));
839 // checkInvariants();
840 }
841
842 /**
843 * Replaces each element of this deque with the result of applying the
844 * operator to that element, as specified by {@link List#replaceAll}.
845 *
846 * @param operator the operator to apply to each element
847 * @since 9
848 */
849 public void replaceAll(UnaryOperator<E> operator) {
850 Objects.requireNonNull(operator);
851 final Object[] elements = this.elements;
852 final int capacity = elements.length;
853 for (int k = size, i = head; --k >= 0; i = inc(i, capacity))
854 elements[i] = operator.apply(elementAt(i));
855 // checkInvariants();
856 }
857
858 /**
859 * @throws NullPointerException {@inheritDoc}
860 */
861 @Override
862 public boolean removeIf(Predicate<? super E> filter) {
863 Objects.requireNonNull(filter);
864 return bulkRemove(filter);
865 }
866
867 /**
868 * @throws NullPointerException {@inheritDoc}
869 */
870 @Override
871 public boolean removeAll(Collection<?> c) {
872 Objects.requireNonNull(c);
873 return bulkRemove(e -> c.contains(e));
874 }
875
876 /**
877 * @throws NullPointerException {@inheritDoc}
878 */
879 @Override
880 public boolean retainAll(Collection<?> c) {
881 Objects.requireNonNull(c);
882 return bulkRemove(e -> !c.contains(e));
883 }
884
885 /** Implementation of bulk remove methods. */
886 private boolean bulkRemove(Predicate<? super E> filter) {
887 // checkInvariants();
888 final Object[] elements = this.elements;
889 final int capacity = elements.length;
890 int i = head, j = i, remaining = size, deleted = 0;
891 try {
892 for (; remaining > 0; remaining--, i = inc(i, capacity)) {
893 @SuppressWarnings("unchecked") E e = (E) elements[i];
894 if (filter.test(e))
895 deleted++;
896 else {
897 if (j != i)
898 elements[j] = e;
899 j = inc(j, capacity);
900 }
901 }
902 return deleted > 0;
903 } catch (Throwable ex) {
904 for (; remaining > 0;
905 remaining--, i = inc(i, capacity), j = inc(j, capacity))
906 elements[j] = elements[i];
907 throw ex;
908 } finally {
909 size -= deleted;
910 for (; --deleted >= 0; j = inc(j, capacity))
911 elements[j] = null;
912 // checkInvariants();
913 }
914 }
915
916 /**
917 * Returns {@code true} if this deque contains the specified element.
918 * More formally, returns {@code true} if and only if this deque contains
919 * at least one element {@code e} such that {@code o.equals(e)}.
920 *
921 * @param o object to be checked for containment in this deque
922 * @return {@code true} if this deque contains the specified element
923 */
924 public boolean contains(Object o) {
925 if (o != null) {
926 final Object[] elements = this.elements;
927 final int capacity = elements.length;
928 for (int k = size, i = head; --k >= 0; i = inc(i, capacity))
929 if (o.equals(elements[i]))
930 return true;
931 }
932 return false;
933 }
934
935 /**
936 * Removes a single instance of the specified element from this deque.
937 * If the deque does not contain the element, it is unchanged.
938 * More formally, removes the first element {@code e} such that
939 * {@code o.equals(e)} (if such an element exists).
940 * Returns {@code true} if this deque contained the specified element
941 * (or equivalently, if this deque changed as a result of the call).
942 *
943 * <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}.
944 *
945 * @param o element to be removed from this deque, if present
946 * @return {@code true} if this deque contained the specified element
947 */
948 public boolean remove(Object o) {
949 return removeFirstOccurrence(o);
950 }
951
952 /**
953 * Removes all of the elements from this deque.
954 * The deque will be empty after this call returns.
955 */
956 public void clear() {
957 final Object[] elements = this.elements;
958 final int capacity = elements.length;
959 final int h = this.head;
960 final int s = size;
961 if (capacity - h >= s)
962 Arrays.fill(elements, h, h + s, null);
963 else {
964 Arrays.fill(elements, h, capacity, null);
965 Arrays.fill(elements, 0, s - capacity + h, null);
966 }
967 size = head = 0;
968 // checkInvariants();
969 }
970
971 /**
972 * Returns an array containing all of the elements in this deque
973 * in proper sequence (from first to last element).
974 *
975 * <p>The returned array will be "safe" in that no references to it are
976 * maintained by this deque. (In other words, this method must allocate
977 * a new array). The caller is thus free to modify the returned array.
978 *
979 * <p>This method acts as bridge between array-based and collection-based
980 * APIs.
981 *
982 * @return an array containing all of the elements in this deque
983 */
984 public Object[] toArray() {
985 final int head = this.head;
986 final int firstLeg;
987 Object[] a = Arrays.copyOfRange(elements, head, head + size);
988 if ((firstLeg = elements.length - head) < size)
989 System.arraycopy(elements, 0, a, firstLeg, size - firstLeg);
990 return a;
991 }
992
993 /**
994 * Returns an array containing all of the elements in this deque in
995 * proper sequence (from first to last element); the runtime type of the
996 * returned array is that of the specified array. If the deque fits in
997 * the specified array, it is returned therein. Otherwise, a new array
998 * is allocated with the runtime type of the specified array and the
999 * size of this deque.
1000 *
1001 * <p>If this deque fits in the specified array with room to spare
1002 * (i.e., the array has more elements than this deque), the element in
1003 * the array immediately following the end of the deque is set to
1004 * {@code null}.
1005 *
1006 * <p>Like the {@link #toArray()} method, this method acts as bridge between
1007 * array-based and collection-based APIs. Further, this method allows
1008 * precise control over the runtime type of the output array, and may,
1009 * under certain circumstances, be used to save allocation costs.
1010 *
1011 * <p>Suppose {@code x} is a deque known to contain only strings.
1012 * The following code can be used to dump the deque into a newly
1013 * allocated array of {@code String}:
1014 *
1015 * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
1016 *
1017 * Note that {@code toArray(new Object[0])} is identical in function to
1018 * {@code toArray()}.
1019 *
1020 * @param a the array into which the elements of the deque are to
1021 * be stored, if it is big enough; otherwise, a new array of the
1022 * same runtime type is allocated for this purpose
1023 * @return an array containing all of the elements in this deque
1024 * @throws ArrayStoreException if the runtime type of the specified array
1025 * is not a supertype of the runtime type of every element in
1026 * this deque
1027 * @throws NullPointerException if the specified array is null
1028 */
1029 @SuppressWarnings("unchecked")
1030 public <T> T[] toArray(T[] a) {
1031 final Object[] elements = this.elements;
1032 final int head = this.head;
1033 final int firstLeg;
1034 boolean wrap = (firstLeg = elements.length - head) < size;
1035 if (size > a.length) {
1036 a = (T[]) Arrays.copyOfRange(elements, head, head + size,
1037 a.getClass());
1038 } else {
1039 System.arraycopy(elements, head, a, 0, wrap ? firstLeg : size);
1040 if (size < a.length)
1041 a[size] = null;
1042 }
1043 if (wrap)
1044 System.arraycopy(elements, 0, a, firstLeg, size - firstLeg);
1045 return a;
1046 }
1047
1048 // *** Object methods ***
1049
1050 /**
1051 * Returns a copy of this deque.
1052 *
1053 * @return a copy of this deque
1054 */
1055 public ArrayDeque<E> clone() {
1056 try {
1057 @SuppressWarnings("unchecked")
1058 ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
1059 result.elements = Arrays.copyOf(elements, elements.length);
1060 return result;
1061 } catch (CloneNotSupportedException e) {
1062 throw new AssertionError();
1063 }
1064 }
1065
1066 private static final long serialVersionUID = 2340985798034038923L;
1067
1068 /**
1069 * Saves this deque to a stream (that is, serializes it).
1070 *
1071 * @param s the stream
1072 * @throws java.io.IOException if an I/O error occurs
1073 * @serialData The current size ({@code int}) of the deque,
1074 * followed by all of its elements (each an object reference) in
1075 * first-to-last order.
1076 */
1077 private void writeObject(java.io.ObjectOutputStream s)
1078 throws java.io.IOException {
1079 s.defaultWriteObject();
1080
1081 // Write out size
1082 s.writeInt(size);
1083
1084 // Write out elements in order.
1085 final Object[] elements = this.elements;
1086 final int capacity = elements.length;
1087 for (int k = size, i = head; --k >= 0; i = inc(i, capacity))
1088 s.writeObject(elements[i]);
1089 }
1090
1091 /**
1092 * Reconstitutes this deque from a stream (that is, deserializes it).
1093 * @param s the stream
1094 * @throws ClassNotFoundException if the class of a serialized object
1095 * could not be found
1096 * @throws java.io.IOException if an I/O error occurs
1097 */
1098 private void readObject(java.io.ObjectInputStream s)
1099 throws java.io.IOException, ClassNotFoundException {
1100 s.defaultReadObject();
1101
1102 // Read in size and allocate array
1103 elements = new Object[size = s.readInt()];
1104
1105 // Read in all elements in the proper order.
1106 for (int i = 0; i < size; i++)
1107 elements[i] = s.readObject();
1108 }
1109
1110 /** debugging */
1111 private void checkInvariants() {
1112 try {
1113 int capacity = elements.length;
1114 assert size >= 0 && size <= capacity;
1115 assert head >= 0 && ((capacity == 0 && head == 0 && size == 0)
1116 || head < capacity);
1117 assert size == 0
1118 || (elements[head] != null && elements[tail()] != null);
1119 assert size == capacity
1120 || (elements[dec(head, capacity)] == null
1121 && elements[inc(tail(), capacity)] == null);
1122 } catch (Throwable t) {
1123 System.err.printf("head=%d size=%d capacity=%d%n",
1124 head, size, elements.length);
1125 System.err.printf("elements=%s%n",
1126 Arrays.toString(elements));
1127 throw t;
1128 }
1129 }
1130
1131 }