Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/util/ArrayDeque.java
38829 views
/*1* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation. Oracle designates this6* particular file as subject to the "Classpath" exception as provided7* by Oracle in the LICENSE file that accompanied this code.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/2324/*25* This file is available under and governed by the GNU General Public26* License version 2 only, as published by the Free Software Foundation.27* However, the following notice accompanied the original version of this28* file:29*30* Written by Josh Bloch of Google Inc. and released to the public domain,31* as explained at http://creativecommons.org/publicdomain/zero/1.0/.32*/3334package java.util;3536import java.io.Serializable;37import java.util.function.Consumer;38import sun.misc.SharedSecrets;3940/**41* Resizable-array implementation of the {@link Deque} interface. Array42* deques have no capacity restrictions; they grow as necessary to support43* usage. They are not thread-safe; in the absence of external44* synchronization, they do not support concurrent access by multiple threads.45* Null elements are prohibited. This class is likely to be faster than46* {@link Stack} when used as a stack, and faster than {@link LinkedList}47* when used as a queue.48*49* <p>Most {@code ArrayDeque} operations run in amortized constant time.50* Exceptions include {@link #remove(Object) remove}, {@link51* #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence52* removeLastOccurrence}, {@link #contains contains}, {@link #iterator53* iterator.remove()}, and the bulk operations, all of which run in linear54* time.55*56* <p>The iterators returned by this class's {@code iterator} method are57* <i>fail-fast</i>: If the deque is modified at any time after the iterator58* is created, in any way except through the iterator's own {@code remove}59* method, the iterator will generally throw a {@link60* ConcurrentModificationException}. Thus, in the face of concurrent61* modification, the iterator fails quickly and cleanly, rather than risking62* arbitrary, non-deterministic behavior at an undetermined time in the63* future.64*65* <p>Note that the fail-fast behavior of an iterator cannot be guaranteed66* as it is, generally speaking, impossible to make any hard guarantees in the67* presence of unsynchronized concurrent modification. Fail-fast iterators68* throw {@code ConcurrentModificationException} on a best-effort basis.69* Therefore, it would be wrong to write a program that depended on this70* exception for its correctness: <i>the fail-fast behavior of iterators71* should be used only to detect bugs.</i>72*73* <p>This class and its iterator implement all of the74* <em>optional</em> methods of the {@link Collection} and {@link75* Iterator} interfaces.76*77* <p>This class is a member of the78* <a href="{@docRoot}/../technotes/guides/collections/index.html">79* Java Collections Framework</a>.80*81* @author Josh Bloch and Doug Lea82* @since 1.683* @param <E> the type of elements held in this collection84*/85public class ArrayDeque<E> extends AbstractCollection<E>86implements Deque<E>, Cloneable, Serializable87{88/**89* The array in which the elements of the deque are stored.90* The capacity of the deque is the length of this array, which is91* always a power of two. The array is never allowed to become92* full, except transiently within an addX method where it is93* resized (see doubleCapacity) immediately upon becoming full,94* thus avoiding head and tail wrapping around to equal each95* other. We also guarantee that all array cells not holding96* deque elements are always null.97*/98transient Object[] elements; // non-private to simplify nested class access99100/**101* The index of the element at the head of the deque (which is the102* element that would be removed by remove() or pop()); or an103* arbitrary number equal to tail if the deque is empty.104*/105transient int head;106107/**108* The index at which the next element would be added to the tail109* of the deque (via addLast(E), add(E), or push(E)).110*/111transient int tail;112113/**114* The minimum capacity that we'll use for a newly created deque.115* Must be a power of 2.116*/117private static final int MIN_INITIAL_CAPACITY = 8;118119// ****** Array allocation and resizing utilities ******120121private static int calculateSize(int numElements) {122int initialCapacity = MIN_INITIAL_CAPACITY;123// Find the best power of two to hold elements.124// Tests "<=" because arrays aren't kept full.125if (numElements >= initialCapacity) {126initialCapacity = numElements;127initialCapacity |= (initialCapacity >>> 1);128initialCapacity |= (initialCapacity >>> 2);129initialCapacity |= (initialCapacity >>> 4);130initialCapacity |= (initialCapacity >>> 8);131initialCapacity |= (initialCapacity >>> 16);132initialCapacity++;133134if (initialCapacity < 0) // Too many elements, must back off135initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements136}137return initialCapacity;138}139140/**141* Allocates empty array to hold the given number of elements.142*143* @param numElements the number of elements to hold144*/145private void allocateElements(int numElements) {146elements = new Object[calculateSize(numElements)];147}148149/**150* Doubles the capacity of this deque. Call only when full, i.e.,151* when head and tail have wrapped around to become equal.152*/153private void doubleCapacity() {154assert head == tail;155int p = head;156int n = elements.length;157int r = n - p; // number of elements to the right of p158int newCapacity = n << 1;159if (newCapacity < 0)160throw new IllegalStateException("Sorry, deque too big");161Object[] a = new Object[newCapacity];162System.arraycopy(elements, p, a, 0, r);163System.arraycopy(elements, 0, a, r, p);164elements = a;165head = 0;166tail = n;167}168169/**170* Copies the elements from our element array into the specified array,171* in order (from first to last element in the deque). It is assumed172* that the array is large enough to hold all elements in the deque.173*174* @return its argument175*/176private <T> T[] copyElements(T[] a) {177if (head < tail) {178System.arraycopy(elements, head, a, 0, size());179} else if (head > tail) {180int headPortionLen = elements.length - head;181System.arraycopy(elements, head, a, 0, headPortionLen);182System.arraycopy(elements, 0, a, headPortionLen, tail);183}184return a;185}186187/**188* Constructs an empty array deque with an initial capacity189* sufficient to hold 16 elements.190*/191public ArrayDeque() {192elements = new Object[16];193}194195/**196* Constructs an empty array deque with an initial capacity197* sufficient to hold the specified number of elements.198*199* @param numElements lower bound on initial capacity of the deque200*/201public ArrayDeque(int numElements) {202allocateElements(numElements);203}204205/**206* Constructs a deque containing the elements of the specified207* collection, in the order they are returned by the collection's208* iterator. (The first element returned by the collection's209* iterator becomes the first element, or <i>front</i> of the210* deque.)211*212* @param c the collection whose elements are to be placed into the deque213* @throws NullPointerException if the specified collection is null214*/215public ArrayDeque(Collection<? extends E> c) {216allocateElements(c.size());217addAll(c);218}219220// The main insertion and extraction methods are addFirst,221// addLast, pollFirst, pollLast. The other methods are defined in222// terms of these.223224/**225* Inserts the specified element at the front of this deque.226*227* @param e the element to add228* @throws NullPointerException if the specified element is null229*/230public void addFirst(E e) {231if (e == null)232throw new NullPointerException();233elements[head = (head - 1) & (elements.length - 1)] = e;234if (head == tail)235doubleCapacity();236}237238/**239* Inserts the specified element at the end of this deque.240*241* <p>This method is equivalent to {@link #add}.242*243* @param e the element to add244* @throws NullPointerException if the specified element is null245*/246public void addLast(E e) {247if (e == null)248throw new NullPointerException();249elements[tail] = e;250if ( (tail = (tail + 1) & (elements.length - 1)) == head)251doubleCapacity();252}253254/**255* Inserts the specified element at the front of this deque.256*257* @param e the element to add258* @return {@code true} (as specified by {@link Deque#offerFirst})259* @throws NullPointerException if the specified element is null260*/261public boolean offerFirst(E e) {262addFirst(e);263return true;264}265266/**267* Inserts the specified element at the end of this deque.268*269* @param e the element to add270* @return {@code true} (as specified by {@link Deque#offerLast})271* @throws NullPointerException if the specified element is null272*/273public boolean offerLast(E e) {274addLast(e);275return true;276}277278/**279* @throws NoSuchElementException {@inheritDoc}280*/281public E removeFirst() {282E x = pollFirst();283if (x == null)284throw new NoSuchElementException();285return x;286}287288/**289* @throws NoSuchElementException {@inheritDoc}290*/291public E removeLast() {292E x = pollLast();293if (x == null)294throw new NoSuchElementException();295return x;296}297298public E pollFirst() {299int h = head;300@SuppressWarnings("unchecked")301E result = (E) elements[h];302// Element is null if deque empty303if (result == null)304return null;305elements[h] = null; // Must null out slot306head = (h + 1) & (elements.length - 1);307return result;308}309310public E pollLast() {311int t = (tail - 1) & (elements.length - 1);312@SuppressWarnings("unchecked")313E result = (E) elements[t];314if (result == null)315return null;316elements[t] = null;317tail = t;318return result;319}320321/**322* @throws NoSuchElementException {@inheritDoc}323*/324public E getFirst() {325@SuppressWarnings("unchecked")326E result = (E) elements[head];327if (result == null)328throw new NoSuchElementException();329return result;330}331332/**333* @throws NoSuchElementException {@inheritDoc}334*/335public E getLast() {336@SuppressWarnings("unchecked")337E result = (E) elements[(tail - 1) & (elements.length - 1)];338if (result == null)339throw new NoSuchElementException();340return result;341}342343@SuppressWarnings("unchecked")344public E peekFirst() {345// elements[head] is null if deque empty346return (E) elements[head];347}348349@SuppressWarnings("unchecked")350public E peekLast() {351return (E) elements[(tail - 1) & (elements.length - 1)];352}353354/**355* Removes the first occurrence of the specified element in this356* deque (when traversing the deque from head to tail).357* If the deque does not contain the element, it is unchanged.358* More formally, removes the first element {@code e} such that359* {@code o.equals(e)} (if such an element exists).360* Returns {@code true} if this deque contained the specified element361* (or equivalently, if this deque changed as a result of the call).362*363* @param o element to be removed from this deque, if present364* @return {@code true} if the deque contained the specified element365*/366public boolean removeFirstOccurrence(Object o) {367if (o == null)368return false;369int mask = elements.length - 1;370int i = head;371Object x;372while ( (x = elements[i]) != null) {373if (o.equals(x)) {374delete(i);375return true;376}377i = (i + 1) & mask;378}379return false;380}381382/**383* Removes the last occurrence of the specified element in this384* deque (when traversing the deque from head to tail).385* If the deque does not contain the element, it is unchanged.386* More formally, removes the last element {@code e} such that387* {@code o.equals(e)} (if such an element exists).388* Returns {@code true} if this deque contained the specified element389* (or equivalently, if this deque changed as a result of the call).390*391* @param o element to be removed from this deque, if present392* @return {@code true} if the deque contained the specified element393*/394public boolean removeLastOccurrence(Object o) {395if (o == null)396return false;397int mask = elements.length - 1;398int i = (tail - 1) & mask;399Object x;400while ( (x = elements[i]) != null) {401if (o.equals(x)) {402delete(i);403return true;404}405i = (i - 1) & mask;406}407return false;408}409410// *** Queue methods ***411412/**413* Inserts the specified element at the end of this deque.414*415* <p>This method is equivalent to {@link #addLast}.416*417* @param e the element to add418* @return {@code true} (as specified by {@link Collection#add})419* @throws NullPointerException if the specified element is null420*/421public boolean add(E e) {422addLast(e);423return true;424}425426/**427* Inserts the specified element at the end of this deque.428*429* <p>This method is equivalent to {@link #offerLast}.430*431* @param e the element to add432* @return {@code true} (as specified by {@link Queue#offer})433* @throws NullPointerException if the specified element is null434*/435public boolean offer(E e) {436return offerLast(e);437}438439/**440* Retrieves and removes the head of the queue represented by this deque.441*442* This method differs from {@link #poll poll} only in that it throws an443* exception if this deque is empty.444*445* <p>This method is equivalent to {@link #removeFirst}.446*447* @return the head of the queue represented by this deque448* @throws NoSuchElementException {@inheritDoc}449*/450public E remove() {451return removeFirst();452}453454/**455* Retrieves and removes the head of the queue represented by this deque456* (in other words, the first element of this deque), or returns457* {@code null} if this deque is empty.458*459* <p>This method is equivalent to {@link #pollFirst}.460*461* @return the head of the queue represented by this deque, or462* {@code null} if this deque is empty463*/464public E poll() {465return pollFirst();466}467468/**469* Retrieves, but does not remove, the head of the queue represented by470* this deque. This method differs from {@link #peek peek} only in471* that it throws an exception if this deque is empty.472*473* <p>This method is equivalent to {@link #getFirst}.474*475* @return the head of the queue represented by this deque476* @throws NoSuchElementException {@inheritDoc}477*/478public E element() {479return getFirst();480}481482/**483* Retrieves, but does not remove, the head of the queue represented by484* this deque, or returns {@code null} if this deque is empty.485*486* <p>This method is equivalent to {@link #peekFirst}.487*488* @return the head of the queue represented by this deque, or489* {@code null} if this deque is empty490*/491public E peek() {492return peekFirst();493}494495// *** Stack methods ***496497/**498* Pushes an element onto the stack represented by this deque. In other499* words, inserts the element at the front of this deque.500*501* <p>This method is equivalent to {@link #addFirst}.502*503* @param e the element to push504* @throws NullPointerException if the specified element is null505*/506public void push(E e) {507addFirst(e);508}509510/**511* Pops an element from the stack represented by this deque. In other512* words, removes and returns the first element of this deque.513*514* <p>This method is equivalent to {@link #removeFirst()}.515*516* @return the element at the front of this deque (which is the top517* of the stack represented by this deque)518* @throws NoSuchElementException {@inheritDoc}519*/520public E pop() {521return removeFirst();522}523524private void checkInvariants() {525assert elements[tail] == null;526assert head == tail ? elements[head] == null :527(elements[head] != null &&528elements[(tail - 1) & (elements.length - 1)] != null);529assert elements[(head - 1) & (elements.length - 1)] == null;530}531532/**533* Removes the element at the specified position in the elements array,534* adjusting head and tail as necessary. This can result in motion of535* elements backwards or forwards in the array.536*537* <p>This method is called delete rather than remove to emphasize538* that its semantics differ from those of {@link List#remove(int)}.539*540* @return true if elements moved backwards541*/542private boolean delete(int i) {543checkInvariants();544final Object[] elements = this.elements;545final int mask = elements.length - 1;546final int h = head;547final int t = tail;548final int front = (i - h) & mask;549final int back = (t - i) & mask;550551// Invariant: head <= i < tail mod circularity552if (front >= ((t - h) & mask))553throw new ConcurrentModificationException();554555// Optimize for least element motion556if (front < back) {557if (h <= i) {558System.arraycopy(elements, h, elements, h + 1, front);559} else { // Wrap around560System.arraycopy(elements, 0, elements, 1, i);561elements[0] = elements[mask];562System.arraycopy(elements, h, elements, h + 1, mask - h);563}564elements[h] = null;565head = (h + 1) & mask;566return false;567} else {568if (i < t) { // Copy the null tail as well569System.arraycopy(elements, i + 1, elements, i, back);570tail = t - 1;571} else { // Wrap around572System.arraycopy(elements, i + 1, elements, i, mask - i);573elements[mask] = elements[0];574System.arraycopy(elements, 1, elements, 0, t);575tail = (t - 1) & mask;576}577return true;578}579}580581// *** Collection Methods ***582583/**584* Returns the number of elements in this deque.585*586* @return the number of elements in this deque587*/588public int size() {589return (tail - head) & (elements.length - 1);590}591592/**593* Returns {@code true} if this deque contains no elements.594*595* @return {@code true} if this deque contains no elements596*/597public boolean isEmpty() {598return head == tail;599}600601/**602* Returns an iterator over the elements in this deque. The elements603* will be ordered from first (head) to last (tail). This is the same604* order that elements would be dequeued (via successive calls to605* {@link #remove} or popped (via successive calls to {@link #pop}).606*607* @return an iterator over the elements in this deque608*/609public Iterator<E> iterator() {610return new DeqIterator();611}612613public Iterator<E> descendingIterator() {614return new DescendingIterator();615}616617private class DeqIterator implements Iterator<E> {618/**619* Index of element to be returned by subsequent call to next.620*/621private int cursor = head;622623/**624* Tail recorded at construction (also in remove), to stop625* iterator and also to check for comodification.626*/627private int fence = tail;628629/**630* Index of element returned by most recent call to next.631* Reset to -1 if element is deleted by a call to remove.632*/633private int lastRet = -1;634635public boolean hasNext() {636return cursor != fence;637}638639public E next() {640if (cursor == fence)641throw new NoSuchElementException();642@SuppressWarnings("unchecked")643E result = (E) elements[cursor];644// This check doesn't catch all possible comodifications,645// but does catch the ones that corrupt traversal646if (tail != fence || result == null)647throw new ConcurrentModificationException();648lastRet = cursor;649cursor = (cursor + 1) & (elements.length - 1);650return result;651}652653public void remove() {654if (lastRet < 0)655throw new IllegalStateException();656if (delete(lastRet)) { // if left-shifted, undo increment in next()657cursor = (cursor - 1) & (elements.length - 1);658fence = tail;659}660lastRet = -1;661}662663public void forEachRemaining(Consumer<? super E> action) {664Objects.requireNonNull(action);665Object[] a = elements;666int m = a.length - 1, f = fence, i = cursor;667cursor = f;668while (i != f) {669@SuppressWarnings("unchecked") E e = (E)a[i];670i = (i + 1) & m;671if (e == null)672throw new ConcurrentModificationException();673action.accept(e);674}675}676}677678private class DescendingIterator implements Iterator<E> {679/*680* This class is nearly a mirror-image of DeqIterator, using681* tail instead of head for initial cursor, and head instead of682* tail for fence.683*/684private int cursor = tail;685private int fence = head;686private int lastRet = -1;687688public boolean hasNext() {689return cursor != fence;690}691692public E next() {693if (cursor == fence)694throw new NoSuchElementException();695cursor = (cursor - 1) & (elements.length - 1);696@SuppressWarnings("unchecked")697E result = (E) elements[cursor];698if (head != fence || result == null)699throw new ConcurrentModificationException();700lastRet = cursor;701return result;702}703704public void remove() {705if (lastRet < 0)706throw new IllegalStateException();707if (!delete(lastRet)) {708cursor = (cursor + 1) & (elements.length - 1);709fence = head;710}711lastRet = -1;712}713}714715/**716* Returns {@code true} if this deque contains the specified element.717* More formally, returns {@code true} if and only if this deque contains718* at least one element {@code e} such that {@code o.equals(e)}.719*720* @param o object to be checked for containment in this deque721* @return {@code true} if this deque contains the specified element722*/723public boolean contains(Object o) {724if (o == null)725return false;726int mask = elements.length - 1;727int i = head;728Object x;729while ( (x = elements[i]) != null) {730if (o.equals(x))731return true;732i = (i + 1) & mask;733}734return false;735}736737/**738* Removes a single instance of the specified element from this deque.739* If the deque does not contain the element, it is unchanged.740* More formally, removes the first element {@code e} such that741* {@code o.equals(e)} (if such an element exists).742* Returns {@code true} if this deque contained the specified element743* (or equivalently, if this deque changed as a result of the call).744*745* <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}.746*747* @param o element to be removed from this deque, if present748* @return {@code true} if this deque contained the specified element749*/750public boolean remove(Object o) {751return removeFirstOccurrence(o);752}753754/**755* Removes all of the elements from this deque.756* The deque will be empty after this call returns.757*/758public void clear() {759int h = head;760int t = tail;761if (h != t) { // clear all cells762head = tail = 0;763int i = h;764int mask = elements.length - 1;765do {766elements[i] = null;767i = (i + 1) & mask;768} while (i != t);769}770}771772/**773* Returns an array containing all of the elements in this deque774* in proper sequence (from first to last element).775*776* <p>The returned array will be "safe" in that no references to it are777* maintained by this deque. (In other words, this method must allocate778* a new array). The caller is thus free to modify the returned array.779*780* <p>This method acts as bridge between array-based and collection-based781* APIs.782*783* @return an array containing all of the elements in this deque784*/785public Object[] toArray() {786return copyElements(new Object[size()]);787}788789/**790* Returns an array containing all of the elements in this deque in791* proper sequence (from first to last element); the runtime type of the792* returned array is that of the specified array. If the deque fits in793* the specified array, it is returned therein. Otherwise, a new array794* is allocated with the runtime type of the specified array and the795* size of this deque.796*797* <p>If this deque fits in the specified array with room to spare798* (i.e., the array has more elements than this deque), the element in799* the array immediately following the end of the deque is set to800* {@code null}.801*802* <p>Like the {@link #toArray()} method, this method acts as bridge between803* array-based and collection-based APIs. Further, this method allows804* precise control over the runtime type of the output array, and may,805* under certain circumstances, be used to save allocation costs.806*807* <p>Suppose {@code x} is a deque known to contain only strings.808* The following code can be used to dump the deque into a newly809* allocated array of {@code String}:810*811* <pre> {@code String[] y = x.toArray(new String[0]);}</pre>812*813* Note that {@code toArray(new Object[0])} is identical in function to814* {@code toArray()}.815*816* @param a the array into which the elements of the deque are to817* be stored, if it is big enough; otherwise, a new array of the818* same runtime type is allocated for this purpose819* @return an array containing all of the elements in this deque820* @throws ArrayStoreException if the runtime type of the specified array821* is not a supertype of the runtime type of every element in822* this deque823* @throws NullPointerException if the specified array is null824*/825@SuppressWarnings("unchecked")826public <T> T[] toArray(T[] a) {827int size = size();828if (a.length < size)829a = (T[])java.lang.reflect.Array.newInstance(830a.getClass().getComponentType(), size);831copyElements(a);832if (a.length > size)833a[size] = null;834return a;835}836837// *** Object methods ***838839/**840* Returns a copy of this deque.841*842* @return a copy of this deque843*/844public ArrayDeque<E> clone() {845try {846@SuppressWarnings("unchecked")847ArrayDeque<E> result = (ArrayDeque<E>) super.clone();848result.elements = Arrays.copyOf(elements, elements.length);849return result;850} catch (CloneNotSupportedException e) {851throw new AssertionError();852}853}854855private static final long serialVersionUID = 2340985798034038923L;856857/**858* Saves this deque to a stream (that is, serializes it).859*860* @serialData The current size ({@code int}) of the deque,861* followed by all of its elements (each an object reference) in862* first-to-last order.863*/864private void writeObject(java.io.ObjectOutputStream s)865throws java.io.IOException {866s.defaultWriteObject();867868// Write out size869s.writeInt(size());870871// Write out elements in order.872int mask = elements.length - 1;873for (int i = head; i != tail; i = (i + 1) & mask)874s.writeObject(elements[i]);875}876877/**878* Reconstitutes this deque from a stream (that is, deserializes it).879*/880private void readObject(java.io.ObjectInputStream s)881throws java.io.IOException, ClassNotFoundException {882s.defaultReadObject();883884// Read in size and allocate array885int size = s.readInt();886int capacity = calculateSize(size);887SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);888allocateElements(size);889head = 0;890tail = size;891892// Read in all elements in the proper order.893for (int i = 0; i < size; i++)894elements[i] = s.readObject();895}896897/**898* Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>899* and <em>fail-fast</em> {@link Spliterator} over the elements in this900* deque.901*902* <p>The {@code Spliterator} reports {@link Spliterator#SIZED},903* {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and904* {@link Spliterator#NONNULL}. Overriding implementations should document905* the reporting of additional characteristic values.906*907* @return a {@code Spliterator} over the elements in this deque908* @since 1.8909*/910public Spliterator<E> spliterator() {911return new DeqSpliterator<E>(this, -1, -1);912}913914static final class DeqSpliterator<E> implements Spliterator<E> {915private final ArrayDeque<E> deq;916private int fence; // -1 until first use917private int index; // current index, modified on traverse/split918919/** Creates new spliterator covering the given array and range */920DeqSpliterator(ArrayDeque<E> deq, int origin, int fence) {921this.deq = deq;922this.index = origin;923this.fence = fence;924}925926private int getFence() { // force initialization927int t;928if ((t = fence) < 0) {929t = fence = deq.tail;930index = deq.head;931}932return t;933}934935public DeqSpliterator<E> trySplit() {936int t = getFence(), h = index, n = deq.elements.length;937if (h != t && ((h + 1) & (n - 1)) != t) {938if (h > t)939t += n;940int m = ((h + t) >>> 1) & (n - 1);941return new DeqSpliterator<>(deq, h, index = m);942}943return null;944}945946public void forEachRemaining(Consumer<? super E> consumer) {947if (consumer == null)948throw new NullPointerException();949Object[] a = deq.elements;950int m = a.length - 1, f = getFence(), i = index;951index = f;952while (i != f) {953@SuppressWarnings("unchecked") E e = (E)a[i];954i = (i + 1) & m;955if (e == null)956throw new ConcurrentModificationException();957consumer.accept(e);958}959}960961public boolean tryAdvance(Consumer<? super E> consumer) {962if (consumer == null)963throw new NullPointerException();964Object[] a = deq.elements;965int m = a.length - 1, f = getFence(), i = index;966if (i != fence) {967@SuppressWarnings("unchecked") E e = (E)a[i];968index = (i + 1) & m;969if (e == null)970throw new ConcurrentModificationException();971consumer.accept(e);972return true;973}974return false;975}976977public long estimateSize() {978int n = getFence() - index;979if (n < 0)980n += deq.elements.length;981return (long) n;982}983984@Override985public int characteristics() {986return Spliterator.ORDERED | Spliterator.SIZED |987Spliterator.NONNULL | Spliterator.SUBSIZED;988}989}990991}992993994