31 * Written by Josh Bloch of Google Inc. and released to the public domain, |
31 * Written by Josh Bloch of Google Inc. and released to the public domain, |
32 * as explained at http://creativecommons.org/publicdomain/zero/1.0/. |
32 * as explained at http://creativecommons.org/publicdomain/zero/1.0/. |
33 */ |
33 */ |
34 |
34 |
35 package java.util; |
35 package java.util; |
36 import java.io.*; |
36 |
|
37 import java.io.Serializable; |
|
38 import java.util.function.Consumer; |
37 |
39 |
38 /** |
40 /** |
39 * Resizable-array implementation of the {@link Deque} interface. Array |
41 * Resizable-array implementation of the {@link Deque} interface. Array |
40 * deques have no capacity restrictions; they grow as necessary to support |
42 * deques have no capacity restrictions; they grow as necessary to support |
41 * usage. They are not thread-safe; in the absence of external |
43 * usage. They are not thread-safe; in the absence of external |
42 * synchronization, they do not support concurrent access by multiple threads. |
44 * synchronization, they do not support concurrent access by multiple threads. |
43 * Null elements are prohibited. This class is likely to be faster than |
45 * Null elements are prohibited. This class is likely to be faster than |
44 * {@link Stack} when used as a stack, and faster than {@link LinkedList} |
46 * {@link Stack} when used as a stack, and faster than {@link LinkedList} |
45 * when used as a queue. |
47 * when used as a queue. |
46 * |
48 * |
47 * <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time. |
49 * <p>Most {@code ArrayDeque} operations run in amortized constant time. |
48 * Exceptions include {@link #remove(Object) remove}, {@link |
50 * Exceptions include {@link #remove(Object) remove}, {@link |
49 * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence |
51 * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence |
50 * removeLastOccurrence}, {@link #contains contains}, {@link #iterator |
52 * removeLastOccurrence}, {@link #contains contains}, {@link #iterator |
51 * iterator.remove()}, and the bulk operations, all of which run in linear |
53 * iterator.remove()}, and the bulk operations, all of which run in linear |
52 * time. |
54 * time. |
53 * |
55 * |
54 * <p>The iterators returned by this class's <tt>iterator</tt> method are |
56 * <p>The iterators returned by this class's {@code iterator} method are |
55 * <i>fail-fast</i>: If the deque is modified at any time after the iterator |
57 * <i>fail-fast</i>: If the deque is modified at any time after the iterator |
56 * is created, in any way except through the iterator's own <tt>remove</tt> |
58 * is created, in any way except through the iterator's own {@code remove} |
57 * method, the iterator will generally throw a {@link |
59 * method, the iterator will generally throw a {@link |
58 * ConcurrentModificationException}. Thus, in the face of concurrent |
60 * ConcurrentModificationException}. Thus, in the face of concurrent |
59 * modification, the iterator fails quickly and cleanly, rather than risking |
61 * modification, the iterator fails quickly and cleanly, rather than risking |
60 * arbitrary, non-deterministic behavior at an undetermined time in the |
62 * arbitrary, non-deterministic behavior at an undetermined time in the |
61 * future. |
63 * future. |
62 * |
64 * |
63 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed |
65 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed |
64 * as it is, generally speaking, impossible to make any hard guarantees in the |
66 * as it is, generally speaking, impossible to make any hard guarantees in the |
65 * presence of unsynchronized concurrent modification. Fail-fast iterators |
67 * presence of unsynchronized concurrent modification. Fail-fast iterators |
66 * throw <tt>ConcurrentModificationException</tt> on a best-effort basis. |
68 * throw {@code ConcurrentModificationException} on a best-effort basis. |
67 * Therefore, it would be wrong to write a program that depended on this |
69 * Therefore, it would be wrong to write a program that depended on this |
68 * exception for its correctness: <i>the fail-fast behavior of iterators |
70 * exception for its correctness: <i>the fail-fast behavior of iterators |
69 * should be used only to detect bugs.</i> |
71 * should be used only to detect bugs.</i> |
70 * |
72 * |
71 * <p>This class and its iterator implement all of the |
73 * <p>This class and its iterator implement all of the |
91 * resized (see doubleCapacity) immediately upon becoming full, |
93 * resized (see doubleCapacity) immediately upon becoming full, |
92 * thus avoiding head and tail wrapping around to equal each |
94 * thus avoiding head and tail wrapping around to equal each |
93 * other. We also guarantee that all array cells not holding |
95 * other. We also guarantee that all array cells not holding |
94 * deque elements are always null. |
96 * deque elements are always null. |
95 */ |
97 */ |
96 private transient E[] elements; |
98 transient Object[] elements; // non-private to simplify nested class access |
97 |
99 |
98 /** |
100 /** |
99 * The index of the element at the head of the deque (which is the |
101 * The index of the element at the head of the deque (which is the |
100 * element that would be removed by remove() or pop()); or an |
102 * element that would be removed by remove() or pop()); or an |
101 * arbitrary number equal to tail if the deque is empty. |
103 * arbitrary number equal to tail if the deque is empty. |
102 */ |
104 */ |
103 private transient int head; |
105 transient int head; |
104 |
106 |
105 /** |
107 /** |
106 * The index at which the next element would be added to the tail |
108 * The index at which the next element would be added to the tail |
107 * of the deque (via addLast(E), add(E), or push(E)). |
109 * of the deque (via addLast(E), add(E), or push(E)). |
108 */ |
110 */ |
109 private transient int tail; |
111 transient int tail; |
110 |
112 |
111 /** |
113 /** |
112 * The minimum capacity that we'll use for a newly created deque. |
114 * The minimum capacity that we'll use for a newly created deque. |
113 * Must be a power of 2. |
115 * Must be a power of 2. |
114 */ |
116 */ |
115 private static final int MIN_INITIAL_CAPACITY = 8; |
117 private static final int MIN_INITIAL_CAPACITY = 8; |
116 |
118 |
117 // ****** Array allocation and resizing utilities ****** |
119 // ****** Array allocation and resizing utilities ****** |
118 |
120 |
119 /** |
121 /** |
120 * Allocate empty array to hold the given number of elements. |
122 * Allocates empty array to hold the given number of elements. |
121 * |
123 * |
122 * @param numElements the number of elements to hold |
124 * @param numElements the number of elements to hold |
123 */ |
125 */ |
124 @SuppressWarnings("unchecked") |
|
125 private void allocateElements(int numElements) { |
126 private void allocateElements(int numElements) { |
126 int initialCapacity = MIN_INITIAL_CAPACITY; |
127 int initialCapacity = MIN_INITIAL_CAPACITY; |
127 // Find the best power of two to hold elements. |
128 // Find the best power of two to hold elements. |
128 // Tests "<=" because arrays aren't kept full. |
129 // Tests "<=" because arrays aren't kept full. |
129 if (numElements >= initialCapacity) { |
130 if (numElements >= initialCapacity) { |
136 initialCapacity++; |
137 initialCapacity++; |
137 |
138 |
138 if (initialCapacity < 0) // Too many elements, must back off |
139 if (initialCapacity < 0) // Too many elements, must back off |
139 initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements |
140 initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements |
140 } |
141 } |
141 elements = (E[]) new Object[initialCapacity]; |
142 elements = new Object[initialCapacity]; |
142 } |
143 } |
143 |
144 |
144 /** |
145 /** |
145 * Double the capacity of this deque. Call only when full, i.e., |
146 * Doubles the capacity of this deque. Call only when full, i.e., |
146 * when head and tail have wrapped around to become equal. |
147 * when head and tail have wrapped around to become equal. |
147 */ |
148 */ |
148 private void doubleCapacity() { |
149 private void doubleCapacity() { |
149 assert head == tail; |
150 assert head == tail; |
150 int p = head; |
151 int p = head; |
151 int n = elements.length; |
152 int n = elements.length; |
152 int r = n - p; // number of elements to the right of p |
153 int r = n - p; // number of elements to the right of p |
153 int newCapacity = n << 1; |
154 int newCapacity = n << 1; |
154 if (newCapacity < 0) |
155 if (newCapacity < 0) |
155 throw new IllegalStateException("Sorry, deque too big"); |
156 throw new IllegalStateException("Sorry, deque too big"); |
156 @SuppressWarnings("unchecked") |
157 Object[] a = new Object[newCapacity]; |
157 E[] a = (E[]) new Object[newCapacity]; |
|
158 System.arraycopy(elements, p, a, 0, r); |
158 System.arraycopy(elements, p, a, 0, r); |
159 System.arraycopy(elements, 0, a, r, p); |
159 System.arraycopy(elements, 0, a, r, p); |
160 elements = a; |
160 elements = a; |
161 head = 0; |
161 head = 0; |
162 tail = n; |
162 tail = n; |
314 |
316 |
315 /** |
317 /** |
316 * @throws NoSuchElementException {@inheritDoc} |
318 * @throws NoSuchElementException {@inheritDoc} |
317 */ |
319 */ |
318 public E getFirst() { |
320 public E getFirst() { |
319 E x = elements[head]; |
321 @SuppressWarnings("unchecked") |
320 if (x == null) |
322 E result = (E) elements[head]; |
|
323 if (result == null) |
321 throw new NoSuchElementException(); |
324 throw new NoSuchElementException(); |
322 return x; |
325 return result; |
323 } |
326 } |
324 |
327 |
325 /** |
328 /** |
326 * @throws NoSuchElementException {@inheritDoc} |
329 * @throws NoSuchElementException {@inheritDoc} |
327 */ |
330 */ |
328 public E getLast() { |
331 public E getLast() { |
329 E x = elements[(tail - 1) & (elements.length - 1)]; |
332 @SuppressWarnings("unchecked") |
330 if (x == null) |
333 E result = (E) elements[(tail - 1) & (elements.length - 1)]; |
|
334 if (result == null) |
331 throw new NoSuchElementException(); |
335 throw new NoSuchElementException(); |
332 return x; |
336 return result; |
333 } |
337 } |
334 |
338 |
|
339 @SuppressWarnings("unchecked") |
335 public E peekFirst() { |
340 public E peekFirst() { |
336 return elements[head]; // elements[head] is null if deque empty |
341 // elements[head] is null if deque empty |
337 } |
342 return (E) elements[head]; |
338 |
343 } |
|
344 |
|
345 @SuppressWarnings("unchecked") |
339 public E peekLast() { |
346 public E peekLast() { |
340 return elements[(tail - 1) & (elements.length - 1)]; |
347 return (E) elements[(tail - 1) & (elements.length - 1)]; |
341 } |
348 } |
342 |
349 |
343 /** |
350 /** |
344 * Removes the first occurrence of the specified element in this |
351 * Removes the first occurrence of the specified element in this |
345 * deque (when traversing the deque from head to tail). |
352 * deque (when traversing the deque from head to tail). |
346 * If the deque does not contain the element, it is unchanged. |
353 * If the deque does not contain the element, it is unchanged. |
347 * More formally, removes the first element <tt>e</tt> such that |
354 * More formally, removes the first element {@code e} such that |
348 * <tt>o.equals(e)</tt> (if such an element exists). |
355 * {@code o.equals(e)} (if such an element exists). |
349 * Returns <tt>true</tt> if this deque contained the specified element |
356 * Returns {@code true} if this deque contained the specified element |
350 * (or equivalently, if this deque changed as a result of the call). |
357 * (or equivalently, if this deque changed as a result of the call). |
351 * |
358 * |
352 * @param o element to be removed from this deque, if present |
359 * @param o element to be removed from this deque, if present |
353 * @return <tt>true</tt> if the deque contained the specified element |
360 * @return {@code true} if the deque contained the specified element |
354 */ |
361 */ |
355 public boolean removeFirstOccurrence(Object o) { |
362 public boolean removeFirstOccurrence(Object o) { |
356 if (o == null) |
363 if (o == null) |
357 return false; |
364 return false; |
358 int mask = elements.length - 1; |
365 int mask = elements.length - 1; |
359 int i = head; |
366 int i = head; |
360 E x; |
367 Object x; |
361 while ( (x = elements[i]) != null) { |
368 while ( (x = elements[i]) != null) { |
362 if (o.equals(x)) { |
369 if (o.equals(x)) { |
363 delete(i); |
370 delete(i); |
364 return true; |
371 return true; |
365 } |
372 } |
370 |
377 |
371 /** |
378 /** |
372 * Removes the last occurrence of the specified element in this |
379 * Removes the last occurrence of the specified element in this |
373 * deque (when traversing the deque from head to tail). |
380 * deque (when traversing the deque from head to tail). |
374 * If the deque does not contain the element, it is unchanged. |
381 * If the deque does not contain the element, it is unchanged. |
375 * More formally, removes the last element <tt>e</tt> such that |
382 * More formally, removes the last element {@code e} such that |
376 * <tt>o.equals(e)</tt> (if such an element exists). |
383 * {@code o.equals(e)} (if such an element exists). |
377 * Returns <tt>true</tt> if this deque contained the specified element |
384 * Returns {@code true} if this deque contained the specified element |
378 * (or equivalently, if this deque changed as a result of the call). |
385 * (or equivalently, if this deque changed as a result of the call). |
379 * |
386 * |
380 * @param o element to be removed from this deque, if present |
387 * @param o element to be removed from this deque, if present |
381 * @return <tt>true</tt> if the deque contained the specified element |
388 * @return {@code true} if the deque contained the specified element |
382 */ |
389 */ |
383 public boolean removeLastOccurrence(Object o) { |
390 public boolean removeLastOccurrence(Object o) { |
384 if (o == null) |
391 if (o == null) |
385 return false; |
392 return false; |
386 int mask = elements.length - 1; |
393 int mask = elements.length - 1; |
387 int i = (tail - 1) & mask; |
394 int i = (tail - 1) & mask; |
388 E x; |
395 Object x; |
389 while ( (x = elements[i]) != null) { |
396 while ( (x = elements[i]) != null) { |
390 if (o.equals(x)) { |
397 if (o.equals(x)) { |
391 delete(i); |
398 delete(i); |
392 return true; |
399 return true; |
393 } |
400 } |
684 lastRet = -1; |
707 lastRet = -1; |
685 } |
708 } |
686 } |
709 } |
687 |
710 |
688 /** |
711 /** |
689 * Returns <tt>true</tt> if this deque contains the specified element. |
712 * Returns {@code true} if this deque contains the specified element. |
690 * More formally, returns <tt>true</tt> if and only if this deque contains |
713 * More formally, returns {@code true} if and only if this deque contains |
691 * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. |
714 * at least one element {@code e} such that {@code o.equals(e)}. |
692 * |
715 * |
693 * @param o object to be checked for containment in this deque |
716 * @param o object to be checked for containment in this deque |
694 * @return <tt>true</tt> if this deque contains the specified element |
717 * @return {@code true} if this deque contains the specified element |
695 */ |
718 */ |
696 public boolean contains(Object o) { |
719 public boolean contains(Object o) { |
697 if (o == null) |
720 if (o == null) |
698 return false; |
721 return false; |
699 int mask = elements.length - 1; |
722 int mask = elements.length - 1; |
700 int i = head; |
723 int i = head; |
701 E x; |
724 Object x; |
702 while ( (x = elements[i]) != null) { |
725 while ( (x = elements[i]) != null) { |
703 if (o.equals(x)) |
726 if (o.equals(x)) |
704 return true; |
727 return true; |
705 i = (i + 1) & mask; |
728 i = (i + 1) & mask; |
706 } |
729 } |
708 } |
731 } |
709 |
732 |
710 /** |
733 /** |
711 * Removes a single instance of the specified element from this deque. |
734 * Removes a single instance of the specified element from this deque. |
712 * If the deque does not contain the element, it is unchanged. |
735 * If the deque does not contain the element, it is unchanged. |
713 * More formally, removes the first element <tt>e</tt> such that |
736 * More formally, removes the first element {@code e} such that |
714 * <tt>o.equals(e)</tt> (if such an element exists). |
737 * {@code o.equals(e)} (if such an element exists). |
715 * Returns <tt>true</tt> if this deque contained the specified element |
738 * Returns {@code true} if this deque contained the specified element |
716 * (or equivalently, if this deque changed as a result of the call). |
739 * (or equivalently, if this deque changed as a result of the call). |
717 * |
740 * |
718 * <p>This method is equivalent to {@link #removeFirstOccurrence}. |
741 * <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}. |
719 * |
742 * |
720 * @param o element to be removed from this deque, if present |
743 * @param o element to be removed from this deque, if present |
721 * @return <tt>true</tt> if this deque contained the specified element |
744 * @return {@code true} if this deque contained the specified element |
722 */ |
745 */ |
723 public boolean remove(Object o) { |
746 public boolean remove(Object o) { |
724 return removeFirstOccurrence(o); |
747 return removeFirstOccurrence(o); |
725 } |
748 } |
726 |
749 |
768 * size of this deque. |
791 * size of this deque. |
769 * |
792 * |
770 * <p>If this deque fits in the specified array with room to spare |
793 * <p>If this deque fits in the specified array with room to spare |
771 * (i.e., the array has more elements than this deque), the element in |
794 * (i.e., the array has more elements than this deque), the element in |
772 * the array immediately following the end of the deque is set to |
795 * the array immediately following the end of the deque is set to |
773 * <tt>null</tt>. |
796 * {@code null}. |
774 * |
797 * |
775 * <p>Like the {@link #toArray()} method, this method acts as bridge between |
798 * <p>Like the {@link #toArray()} method, this method acts as bridge between |
776 * array-based and collection-based APIs. Further, this method allows |
799 * array-based and collection-based APIs. Further, this method allows |
777 * precise control over the runtime type of the output array, and may, |
800 * precise control over the runtime type of the output array, and may, |
778 * under certain circumstances, be used to save allocation costs. |
801 * under certain circumstances, be used to save allocation costs. |
779 * |
802 * |
780 * <p>Suppose <tt>x</tt> is a deque known to contain only strings. |
803 * <p>Suppose {@code x} is a deque known to contain only strings. |
781 * The following code can be used to dump the deque into a newly |
804 * The following code can be used to dump the deque into a newly |
782 * allocated array of <tt>String</tt>: |
805 * allocated array of {@code String}: |
783 * |
806 * |
784 * <pre> |
807 * <pre> {@code String[] y = x.toArray(new String[0]);}</pre> |
785 * String[] y = x.toArray(new String[0]);</pre> |
808 * |
786 * |
809 * Note that {@code toArray(new Object[0])} is identical in function to |
787 * Note that <tt>toArray(new Object[0])</tt> is identical in function to |
810 * {@code toArray()}. |
788 * <tt>toArray()</tt>. |
|
789 * |
811 * |
790 * @param a the array into which the elements of the deque are to |
812 * @param a the array into which the elements of the deque are to |
791 * be stored, if it is big enough; otherwise, a new array of the |
813 * be stored, if it is big enough; otherwise, a new array of the |
792 * same runtime type is allocated for this purpose |
814 * same runtime type is allocated for this purpose |
793 * @return an array containing all of the elements in this deque |
815 * @return an array containing all of the elements in this deque |
816 * @return a copy of this deque |
838 * @return a copy of this deque |
817 */ |
839 */ |
818 public ArrayDeque<E> clone() { |
840 public ArrayDeque<E> clone() { |
819 try { |
841 try { |
820 @SuppressWarnings("unchecked") |
842 @SuppressWarnings("unchecked") |
821 ArrayDeque<E> result = (ArrayDeque<E>) super.clone(); |
843 ArrayDeque<E> result = (ArrayDeque<E>) super.clone(); |
822 result.elements = Arrays.copyOf(elements, elements.length); |
844 result.elements = Arrays.copyOf(elements, elements.length); |
823 return result; |
845 return result; |
824 |
|
825 } catch (CloneNotSupportedException e) { |
846 } catch (CloneNotSupportedException e) { |
826 throw new AssertionError(); |
847 throw new AssertionError(); |
827 } |
848 } |
828 } |
849 } |
829 |
850 |
830 /** |
|
831 * Appease the serialization gods. |
|
832 */ |
|
833 private static final long serialVersionUID = 2340985798034038923L; |
851 private static final long serialVersionUID = 2340985798034038923L; |
834 |
852 |
835 /** |
853 /** |
836 * Serialize this deque. |
854 * Saves this deque to a stream (that is, serializes it). |
837 * |
855 * |
838 * @serialData The current size (<tt>int</tt>) of the deque, |
856 * @serialData The current size ({@code int}) of the deque, |
839 * followed by all of its elements (each an object reference) in |
857 * followed by all of its elements (each an object reference) in |
840 * first-to-last order. |
858 * first-to-last order. |
841 */ |
859 */ |
842 private void writeObject(ObjectOutputStream s) throws IOException { |
860 private void writeObject(java.io.ObjectOutputStream s) |
|
861 throws java.io.IOException { |
843 s.defaultWriteObject(); |
862 s.defaultWriteObject(); |
844 |
863 |
845 // Write out size |
864 // Write out size |
846 s.writeInt(size()); |
865 s.writeInt(size()); |
847 |
866 |
850 for (int i = head; i != tail; i = (i + 1) & mask) |
869 for (int i = head; i != tail; i = (i + 1) & mask) |
851 s.writeObject(elements[i]); |
870 s.writeObject(elements[i]); |
852 } |
871 } |
853 |
872 |
854 /** |
873 /** |
855 * Deserialize this deque. |
874 * Reconstitutes this deque from a stream (that is, deserializes it). |
856 */ |
875 */ |
857 @SuppressWarnings("unchecked") |
876 private void readObject(java.io.ObjectInputStream s) |
858 private void readObject(ObjectInputStream s) |
877 throws java.io.IOException, ClassNotFoundException { |
859 throws IOException, ClassNotFoundException { |
|
860 s.defaultReadObject(); |
878 s.defaultReadObject(); |
861 |
879 |
862 // Read in size and allocate array |
880 // Read in size and allocate array |
863 int size = s.readInt(); |
881 int size = s.readInt(); |
864 allocateElements(size); |
882 allocateElements(size); |
865 head = 0; |
883 head = 0; |
866 tail = size; |
884 tail = size; |
867 |
885 |
868 // Read in all elements in the proper order. |
886 // Read in all elements in the proper order. |
869 for (int i = 0; i < size; i++) |
887 for (int i = 0; i < size; i++) |
870 elements[i] = (E)s.readObject(); |
888 elements[i] = s.readObject(); |
871 } |
889 } |
|
890 |
|
891 public Spliterator<E> spliterator() { |
|
892 return new DeqSpliterator<E>(this, -1, -1); |
|
893 } |
|
894 |
|
895 static final class DeqSpliterator<E> implements Spliterator<E> { |
|
896 private final ArrayDeque<E> deq; |
|
897 private int fence; // -1 until first use |
|
898 private int index; // current index, modified on traverse/split |
|
899 |
|
900 /** Creates new spliterator covering the given array and range */ |
|
901 DeqSpliterator(ArrayDeque<E> deq, int origin, int fence) { |
|
902 this.deq = deq; |
|
903 this.index = origin; |
|
904 this.fence = fence; |
|
905 } |
|
906 |
|
907 private int getFence() { // force initialization |
|
908 int t; |
|
909 if ((t = fence) < 0) { |
|
910 t = fence = deq.tail; |
|
911 index = deq.head; |
|
912 } |
|
913 return t; |
|
914 } |
|
915 |
|
916 public DeqSpliterator<E> trySplit() { |
|
917 int t = getFence(), h = index, n = deq.elements.length; |
|
918 if (h != t && ((h + 1) & (n - 1)) != t) { |
|
919 if (h > t) |
|
920 t += n; |
|
921 int m = ((h + t) >>> 1) & (n - 1); |
|
922 return new DeqSpliterator<>(deq, h, index = m); |
|
923 } |
|
924 return null; |
|
925 } |
|
926 |
|
927 public void forEachRemaining(Consumer<? super E> consumer) { |
|
928 if (consumer == null) |
|
929 throw new NullPointerException(); |
|
930 Object[] a = deq.elements; |
|
931 int m = a.length - 1, f = getFence(), i = index; |
|
932 index = f; |
|
933 while (i != f) { |
|
934 @SuppressWarnings("unchecked") E e = (E)a[i]; |
|
935 i = (i + 1) & m; |
|
936 if (e == null) |
|
937 throw new ConcurrentModificationException(); |
|
938 consumer.accept(e); |
|
939 } |
|
940 } |
|
941 |
|
942 public boolean tryAdvance(Consumer<? super E> consumer) { |
|
943 if (consumer == null) |
|
944 throw new NullPointerException(); |
|
945 Object[] a = deq.elements; |
|
946 int m = a.length - 1, f = getFence(), i = index; |
|
947 if (i != fence) { |
|
948 @SuppressWarnings("unchecked") E e = (E)a[i]; |
|
949 index = (i + 1) & m; |
|
950 if (e == null) |
|
951 throw new ConcurrentModificationException(); |
|
952 consumer.accept(e); |
|
953 return true; |
|
954 } |
|
955 return false; |
|
956 } |
|
957 |
|
958 public long estimateSize() { |
|
959 int n = getFence() - index; |
|
960 if (n < 0) |
|
961 n += deq.elements.length; |
|
962 return (long) n; |
|
963 } |
|
964 |
|
965 @Override |
|
966 public int characteristics() { |
|
967 return Spliterator.ORDERED | Spliterator.SIZED | |
|
968 Spliterator.NONNULL | Spliterator.SUBSIZED; |
|
969 } |
|
970 } |
|
971 |
872 } |
972 } |