ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/ArrayDeque.java
Revision: 1.88
Committed: Mon Oct 24 16:01:25 2016 UTC (7 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.87: +1 -1 lines
Log Message:
make elementAt private

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