ArrayList.java revision 9eca269fb2932fb9fd99b6e898600e7a21ade0e0
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.  Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23 * or visit www.oracle.com if you need additional information or have any
24 * questions.
25 */
26
27package java.util;
28
29import java.util.function.Consumer;
30import java.util.function.Predicate;
31import java.util.function.UnaryOperator;
32
33/**
34 * Resizable-array implementation of the <tt>List</tt> interface.  Implements
35 * all optional list operations, and permits all elements, including
36 * <tt>null</tt>.  In addition to implementing the <tt>List</tt> interface,
37 * this class provides methods to manipulate the size of the array that is
38 * used internally to store the list.  (This class is roughly equivalent to
39 * <tt>Vector</tt>, except that it is unsynchronized.)
40 *
41 * <p>The <tt>size</tt>, <tt>isEmpty</tt>, <tt>get</tt>, <tt>set</tt>,
42 * <tt>iterator</tt>, and <tt>listIterator</tt> operations run in constant
43 * time.  The <tt>add</tt> operation runs in <i>amortized constant time</i>,
44 * that is, adding n elements requires O(n) time.  All of the other operations
45 * run in linear time (roughly speaking).  The constant factor is low compared
46 * to that for the <tt>LinkedList</tt> implementation.
47 *
48 * <p>Each <tt>ArrayList</tt> instance has a <i>capacity</i>.  The capacity is
49 * the size of the array used to store the elements in the list.  It is always
50 * at least as large as the list size.  As elements are added to an ArrayList,
51 * its capacity grows automatically.  The details of the growth policy are not
52 * specified beyond the fact that adding an element has constant amortized
53 * time cost.
54 *
55 * <p>An application can increase the capacity of an <tt>ArrayList</tt> instance
56 * before adding a large number of elements using the <tt>ensureCapacity</tt>
57 * operation.  This may reduce the amount of incremental reallocation.
58 *
59 * <p><strong>Note that this implementation is not synchronized.</strong>
60 * If multiple threads access an <tt>ArrayList</tt> instance concurrently,
61 * and at least one of the threads modifies the list structurally, it
62 * <i>must</i> be synchronized externally.  (A structural modification is
63 * any operation that adds or deletes one or more elements, or explicitly
64 * resizes the backing array; merely setting the value of an element is not
65 * a structural modification.)  This is typically accomplished by
66 * synchronizing on some object that naturally encapsulates the list.
67 *
68 * If no such object exists, the list should be "wrapped" using the
69 * {@link Collections#synchronizedList Collections.synchronizedList}
70 * method.  This is best done at creation time, to prevent accidental
71 * unsynchronized access to the list:<pre>
72 *   List list = Collections.synchronizedList(new ArrayList(...));</pre>
73 *
74 * <p><a name="fail-fast">
75 * The iterators returned by this class's {@link #iterator() iterator} and
76 * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:</a>
77 * if the list is structurally modified at any time after the iterator is
78 * created, in any way except through the iterator's own
79 * {@link ListIterator#remove() remove} or
80 * {@link ListIterator#add(Object) add} methods, the iterator will throw a
81 * {@link ConcurrentModificationException}.  Thus, in the face of
82 * concurrent modification, the iterator fails quickly and cleanly, rather
83 * than risking arbitrary, non-deterministic behavior at an undetermined
84 * time in the future.
85 *
86 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
87 * as it is, generally speaking, impossible to make any hard guarantees in the
88 * presence of unsynchronized concurrent modification.  Fail-fast iterators
89 * throw {@code ConcurrentModificationException} on a best-effort basis.
90 * Therefore, it would be wrong to write a program that depended on this
91 * exception for its correctness:  <i>the fail-fast behavior of iterators
92 * should be used only to detect bugs.</i>
93 *
94 * <p>This class is a member of the
95 * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">
96 * Java Collections Framework</a>.
97 *
98 * @author  Josh Bloch
99 * @author  Neal Gafter
100 * @see     Collection
101 * @see     List
102 * @see     LinkedList
103 * @see     Vector
104 * @since   1.2
105 */
106// Android-changed: Inlined methods; CME in iterators; throw AIOOBE when toIndex < fromIndex.
107/*
108 * - AOSP commit 3be987f0f18648b3c532c8b89d09505e18594241
109 *   Inline for improved performance:
110 *   - checkForComodification
111 *   - elementData()
112 *   - rangeCheck()
113 *   - rangeCheckForAdd()
114 * - AOSP commit b10b2a3ab693cfd6156d06ffe4e00ce69b9c9194
115 *   Fix ConcurrentModificationException in ArrayList iterators.
116 * - AOSP commit a68b1a5ba82ef8cc19aafdce7d9c7f9631943f84
117 *   Throw AIOOBE when toIndex < fromIndex.
118 */
119public class ArrayList<E> extends AbstractList<E>
120        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
121{
122    private static final long serialVersionUID = 8683452581122892189L;
123
124    /**
125     * Default initial capacity.
126     */
127    private static final int DEFAULT_CAPACITY = 10;
128
129    /**
130     * Shared empty array instance used for empty instances.
131     */
132    private static final Object[] EMPTY_ELEMENTDATA = {};
133
134    /**
135     * Shared empty array instance used for default sized empty instances. We
136     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
137     * first element is added.
138     */
139    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
140
141    /**
142     * The array buffer into which the elements of the ArrayList are stored.
143     * The capacity of the ArrayList is the length of this array buffer. Any
144     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
145     * will be expanded to DEFAULT_CAPACITY when the first element is added.
146     */
147    // Android-note: Also accessed from java.util.Collections
148    transient Object[] elementData; // non-private to simplify nested class access
149
150    /**
151     * The size of the ArrayList (the number of elements it contains).
152     *
153     * @serial
154     */
155    private int size;
156
157    /**
158     * Constructs an empty list with the specified initial capacity.
159     *
160     * @param  initialCapacity  the initial capacity of the list
161     * @throws IllegalArgumentException if the specified initial capacity
162     *         is negative
163     */
164    public ArrayList(int initialCapacity) {
165        if (initialCapacity > 0) {
166            this.elementData = new Object[initialCapacity];
167        } else if (initialCapacity == 0) {
168            this.elementData = EMPTY_ELEMENTDATA;
169        } else {
170            throw new IllegalArgumentException("Illegal Capacity: "+
171                                               initialCapacity);
172        }
173    }
174
175    /**
176     * Constructs an empty list with an initial capacity of ten.
177     */
178    public ArrayList() {
179        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
180    }
181
182    /**
183     * Constructs a list containing the elements of the specified
184     * collection, in the order they are returned by the collection's
185     * iterator.
186     *
187     * @param c the collection whose elements are to be placed into this list
188     * @throws NullPointerException if the specified collection is null
189     */
190    public ArrayList(Collection<? extends E> c) {
191        elementData = c.toArray();
192        if ((size = elementData.length) != 0) {
193            // c.toArray might (incorrectly) not return Object[] (see 6260652)
194            if (elementData.getClass() != Object[].class)
195                elementData = Arrays.copyOf(elementData, size, Object[].class);
196        } else {
197            // replace with empty array.
198            this.elementData = EMPTY_ELEMENTDATA;
199        }
200    }
201
202    /**
203     * Trims the capacity of this <tt>ArrayList</tt> instance to be the
204     * list's current size.  An application can use this operation to minimize
205     * the storage of an <tt>ArrayList</tt> instance.
206     */
207    public void trimToSize() {
208        modCount++;
209        if (size < elementData.length) {
210            elementData = (size == 0)
211              ? EMPTY_ELEMENTDATA
212              : Arrays.copyOf(elementData, size);
213        }
214    }
215
216    /**
217     * Increases the capacity of this <tt>ArrayList</tt> instance, if
218     * necessary, to ensure that it can hold at least the number of elements
219     * specified by the minimum capacity argument.
220     *
221     * @param   minCapacity   the desired minimum capacity
222     */
223    public void ensureCapacity(int minCapacity) {
224        int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
225            // any size if not default element table
226            ? 0
227            // larger than default for default empty table. It's already
228            // supposed to be at default size.
229            : DEFAULT_CAPACITY;
230
231        if (minCapacity > minExpand) {
232            ensureExplicitCapacity(minCapacity);
233        }
234    }
235
236    private void ensureCapacityInternal(int minCapacity) {
237        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
238            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
239        }
240
241        ensureExplicitCapacity(minCapacity);
242    }
243
244    private void ensureExplicitCapacity(int minCapacity) {
245        modCount++;
246
247        // overflow-conscious code
248        if (minCapacity - elementData.length > 0)
249            grow(minCapacity);
250    }
251
252    /**
253     * The maximum size of array to allocate.
254     * Some VMs reserve some header words in an array.
255     * Attempts to allocate larger arrays may result in
256     * OutOfMemoryError: Requested array size exceeds VM limit
257     */
258    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
259
260    /**
261     * Increases the capacity to ensure that it can hold at least the
262     * number of elements specified by the minimum capacity argument.
263     *
264     * @param minCapacity the desired minimum capacity
265     */
266    private void grow(int minCapacity) {
267        // overflow-conscious code
268        int oldCapacity = elementData.length;
269        int newCapacity = oldCapacity + (oldCapacity >> 1);
270        if (newCapacity - minCapacity < 0)
271            newCapacity = minCapacity;
272        if (newCapacity - MAX_ARRAY_SIZE > 0)
273            newCapacity = hugeCapacity(minCapacity);
274        // minCapacity is usually close to size, so this is a win:
275        elementData = Arrays.copyOf(elementData, newCapacity);
276    }
277
278    private static int hugeCapacity(int minCapacity) {
279        if (minCapacity < 0) // overflow
280            throw new OutOfMemoryError();
281        return (minCapacity > MAX_ARRAY_SIZE) ?
282            Integer.MAX_VALUE :
283            MAX_ARRAY_SIZE;
284    }
285
286    /**
287     * Returns the number of elements in this list.
288     *
289     * @return the number of elements in this list
290     */
291    public int size() {
292        return size;
293    }
294
295    /**
296     * Returns <tt>true</tt> if this list contains no elements.
297     *
298     * @return <tt>true</tt> if this list contains no elements
299     */
300    public boolean isEmpty() {
301        return size == 0;
302    }
303
304    /**
305     * Returns <tt>true</tt> if this list contains the specified element.
306     * More formally, returns <tt>true</tt> if and only if this list contains
307     * at least one element <tt>e</tt> such that
308     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
309     *
310     * @param o element whose presence in this list is to be tested
311     * @return <tt>true</tt> if this list contains the specified element
312     */
313    public boolean contains(Object o) {
314        return indexOf(o) >= 0;
315    }
316
317    /**
318     * Returns the index of the first occurrence of the specified element
319     * in this list, or -1 if this list does not contain the element.
320     * More formally, returns the lowest index <tt>i</tt> such that
321     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
322     * or -1 if there is no such index.
323     */
324    public int indexOf(Object o) {
325        if (o == null) {
326            for (int i = 0; i < size; i++)
327                if (elementData[i]==null)
328                    return i;
329        } else {
330            for (int i = 0; i < size; i++)
331                if (o.equals(elementData[i]))
332                    return i;
333        }
334        return -1;
335    }
336
337    /**
338     * Returns the index of the last occurrence of the specified element
339     * in this list, or -1 if this list does not contain the element.
340     * More formally, returns the highest index <tt>i</tt> such that
341     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
342     * or -1 if there is no such index.
343     */
344    public int lastIndexOf(Object o) {
345        if (o == null) {
346            for (int i = size-1; i >= 0; i--)
347                if (elementData[i]==null)
348                    return i;
349        } else {
350            for (int i = size-1; i >= 0; i--)
351                if (o.equals(elementData[i]))
352                    return i;
353        }
354        return -1;
355    }
356
357    /**
358     * Returns a shallow copy of this <tt>ArrayList</tt> instance.  (The
359     * elements themselves are not copied.)
360     *
361     * @return a clone of this <tt>ArrayList</tt> instance
362     */
363    public Object clone() {
364        try {
365            ArrayList<?> v = (ArrayList<?>) super.clone();
366            v.elementData = Arrays.copyOf(elementData, size);
367            v.modCount = 0;
368            return v;
369        } catch (CloneNotSupportedException e) {
370            // this shouldn't happen, since we are Cloneable
371            throw new InternalError(e);
372        }
373    }
374
375    /**
376     * Returns an array containing all of the elements in this list
377     * in proper sequence (from first to last element).
378     *
379     * <p>The returned array will be "safe" in that no references to it are
380     * maintained by this list.  (In other words, this method must allocate
381     * a new array).  The caller is thus free to modify the returned array.
382     *
383     * <p>This method acts as bridge between array-based and collection-based
384     * APIs.
385     *
386     * @return an array containing all of the elements in this list in
387     *         proper sequence
388     */
389    public Object[] toArray() {
390        return Arrays.copyOf(elementData, size);
391    }
392
393    /**
394     * Returns an array containing all of the elements in this list in proper
395     * sequence (from first to last element); the runtime type of the returned
396     * array is that of the specified array.  If the list fits in the
397     * specified array, it is returned therein.  Otherwise, a new array is
398     * allocated with the runtime type of the specified array and the size of
399     * this list.
400     *
401     * <p>If the list fits in the specified array with room to spare
402     * (i.e., the array has more elements than the list), the element in
403     * the array immediately following the end of the collection is set to
404     * <tt>null</tt>.  (This is useful in determining the length of the
405     * list <i>only</i> if the caller knows that the list does not contain
406     * any null elements.)
407     *
408     * @param a the array into which the elements of the list are to
409     *          be stored, if it is big enough; otherwise, a new array of the
410     *          same runtime type is allocated for this purpose.
411     * @return an array containing the elements of the list
412     * @throws ArrayStoreException if the runtime type of the specified array
413     *         is not a supertype of the runtime type of every element in
414     *         this list
415     * @throws NullPointerException if the specified array is null
416     */
417    @SuppressWarnings("unchecked")
418    public <T> T[] toArray(T[] a) {
419        if (a.length < size)
420            // Make a new array of a's runtime type, but my contents:
421            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
422        System.arraycopy(elementData, 0, a, 0, size);
423        if (a.length > size)
424            a[size] = null;
425        return a;
426    }
427
428    /**
429     * Returns the element at the specified position in this list.
430     *
431     * @param  index index of the element to return
432     * @return the element at the specified position in this list
433     * @throws IndexOutOfBoundsException {@inheritDoc}
434     */
435    public E get(int index) {
436        if (index >= size)
437            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
438
439        return (E) elementData[index];
440    }
441
442    /**
443     * Replaces the element at the specified position in this list with
444     * the specified element.
445     *
446     * @param index index of the element to replace
447     * @param element element to be stored at the specified position
448     * @return the element previously at the specified position
449     * @throws IndexOutOfBoundsException {@inheritDoc}
450     */
451    public E set(int index, E element) {
452        if (index >= size)
453            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
454
455        E oldValue = (E) elementData[index];
456        elementData[index] = element;
457        return oldValue;
458    }
459
460    /**
461     * Appends the specified element to the end of this list.
462     *
463     * @param e element to be appended to this list
464     * @return <tt>true</tt> (as specified by {@link Collection#add})
465     */
466    public boolean add(E e) {
467        ensureCapacityInternal(size + 1);  // Increments modCount!!
468        elementData[size++] = e;
469        return true;
470    }
471
472    /**
473     * Inserts the specified element at the specified position in this
474     * list. Shifts the element currently at that position (if any) and
475     * any subsequent elements to the right (adds one to their indices).
476     *
477     * @param index index at which the specified element is to be inserted
478     * @param element element to be inserted
479     * @throws IndexOutOfBoundsException {@inheritDoc}
480     */
481    public void add(int index, E element) {
482        if (index > size || index < 0)
483            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
484
485        ensureCapacityInternal(size + 1);  // Increments modCount!!
486        System.arraycopy(elementData, index, elementData, index + 1,
487                         size - index);
488        elementData[index] = element;
489        size++;
490    }
491
492    /**
493     * Removes the element at the specified position in this list.
494     * Shifts any subsequent elements to the left (subtracts one from their
495     * indices).
496     *
497     * @param index the index of the element to be removed
498     * @return the element that was removed from the list
499     * @throws IndexOutOfBoundsException {@inheritDoc}
500     */
501    public E remove(int index) {
502        if (index >= size)
503            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
504
505        modCount++;
506        E oldValue = (E) elementData[index];
507
508        int numMoved = size - index - 1;
509        if (numMoved > 0)
510            System.arraycopy(elementData, index+1, elementData, index,
511                             numMoved);
512        elementData[--size] = null; // clear to let GC do its work
513
514        return oldValue;
515    }
516
517    /**
518     * Removes the first occurrence of the specified element from this list,
519     * if it is present.  If the list does not contain the element, it is
520     * unchanged.  More formally, removes the element with the lowest index
521     * <tt>i</tt> such that
522     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
523     * (if such an element exists).  Returns <tt>true</tt> if this list
524     * contained the specified element (or equivalently, if this list
525     * changed as a result of the call).
526     *
527     * @param o element to be removed from this list, if present
528     * @return <tt>true</tt> if this list contained the specified element
529     */
530    public boolean remove(Object o) {
531        if (o == null) {
532            for (int index = 0; index < size; index++)
533                if (elementData[index] == null) {
534                    fastRemove(index);
535                    return true;
536                }
537        } else {
538            for (int index = 0; index < size; index++)
539                if (o.equals(elementData[index])) {
540                    fastRemove(index);
541                    return true;
542                }
543        }
544        return false;
545    }
546
547    /*
548     * Private remove method that skips bounds checking and does not
549     * return the value removed.
550     */
551    private void fastRemove(int index) {
552        modCount++;
553        int numMoved = size - index - 1;
554        if (numMoved > 0)
555            System.arraycopy(elementData, index+1, elementData, index,
556                             numMoved);
557        elementData[--size] = null; // clear to let GC do its work
558    }
559
560    /**
561     * Removes all of the elements from this list.  The list will
562     * be empty after this call returns.
563     */
564    public void clear() {
565        modCount++;
566
567        // clear to let GC do its work
568        for (int i = 0; i < size; i++)
569            elementData[i] = null;
570
571        size = 0;
572    }
573
574    /**
575     * Appends all of the elements in the specified collection to the end of
576     * this list, in the order that they are returned by the
577     * specified collection's Iterator.  The behavior of this operation is
578     * undefined if the specified collection is modified while the operation
579     * is in progress.  (This implies that the behavior of this call is
580     * undefined if the specified collection is this list, and this
581     * list is nonempty.)
582     *
583     * @param c collection containing elements to be added to this list
584     * @return <tt>true</tt> if this list changed as a result of the call
585     * @throws NullPointerException if the specified collection is null
586     */
587    public boolean addAll(Collection<? extends E> c) {
588        Object[] a = c.toArray();
589        int numNew = a.length;
590        ensureCapacityInternal(size + numNew);  // Increments modCount
591        System.arraycopy(a, 0, elementData, size, numNew);
592        size += numNew;
593        return numNew != 0;
594    }
595
596    /**
597     * Inserts all of the elements in the specified collection into this
598     * list, starting at the specified position.  Shifts the element
599     * currently at that position (if any) and any subsequent elements to
600     * the right (increases their indices).  The new elements will appear
601     * in the list in the order that they are returned by the
602     * specified collection's iterator.
603     *
604     * @param index index at which to insert the first element from the
605     *              specified collection
606     * @param c collection containing elements to be added to this list
607     * @return <tt>true</tt> if this list changed as a result of the call
608     * @throws IndexOutOfBoundsException {@inheritDoc}
609     * @throws NullPointerException if the specified collection is null
610     */
611    public boolean addAll(int index, Collection<? extends E> c) {
612        if (index > size || index < 0)
613            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
614
615        Object[] a = c.toArray();
616        int numNew = a.length;
617        ensureCapacityInternal(size + numNew);  // Increments modCount
618
619        int numMoved = size - index;
620        if (numMoved > 0)
621            System.arraycopy(elementData, index, elementData, index + numNew,
622                             numMoved);
623
624        System.arraycopy(a, 0, elementData, index, numNew);
625        size += numNew;
626        return numNew != 0;
627    }
628
629    /**
630     * Removes from this list all of the elements whose index is between
631     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
632     * Shifts any succeeding elements to the left (reduces their index).
633     * This call shortens the list by {@code (toIndex - fromIndex)} elements.
634     * (If {@code toIndex==fromIndex}, this operation has no effect.)
635     *
636     * @throws IndexOutOfBoundsException if {@code fromIndex} or
637     *         {@code toIndex} is out of range
638     *         ({@code fromIndex < 0 ||
639     *          fromIndex >= size() ||
640     *          toIndex > size() ||
641     *          toIndex < fromIndex})
642     */
643    protected void removeRange(int fromIndex, int toIndex) {
644        // Android-changed: Throw an IOOBE if toIndex < fromIndex as documented.
645        // All the other cases (negative indices, or indices greater than the size
646        // will be thrown by System#arrayCopy.
647        if (toIndex < fromIndex) {
648            throw new IndexOutOfBoundsException("toIndex < fromIndex");
649        }
650
651        modCount++;
652        int numMoved = size - toIndex;
653        System.arraycopy(elementData, toIndex, elementData, fromIndex,
654                         numMoved);
655
656        // clear to let GC do its work
657        int newSize = size - (toIndex-fromIndex);
658        for (int i = newSize; i < size; i++) {
659            elementData[i] = null;
660        }
661        size = newSize;
662    }
663
664    /**
665     * Constructs an IndexOutOfBoundsException detail message.
666     * Of the many possible refactorings of the error handling code,
667     * this "outlining" performs best with both server and client VMs.
668     */
669    private String outOfBoundsMsg(int index) {
670        return "Index: "+index+", Size: "+size;
671    }
672
673    /**
674     * Removes from this list all of its elements that are contained in the
675     * specified collection.
676     *
677     * @param c collection containing elements to be removed from this list
678     * @return {@code true} if this list changed as a result of the call
679     * @throws ClassCastException if the class of an element of this list
680     *         is incompatible with the specified collection
681     * (<a href="Collection.html#optional-restrictions">optional</a>)
682     * @throws NullPointerException if this list contains a null element and the
683     *         specified collection does not permit null elements
684     * (<a href="Collection.html#optional-restrictions">optional</a>),
685     *         or if the specified collection is null
686     * @see Collection#contains(Object)
687     */
688    public boolean removeAll(Collection<?> c) {
689        Objects.requireNonNull(c);
690        return batchRemove(c, false);
691    }
692
693    /**
694     * Retains only the elements in this list that are contained in the
695     * specified collection.  In other words, removes from this list all
696     * of its elements that are not contained in the specified collection.
697     *
698     * @param c collection containing elements to be retained in this list
699     * @return {@code true} if this list changed as a result of the call
700     * @throws ClassCastException if the class of an element of this list
701     *         is incompatible with the specified collection
702     * (<a href="Collection.html#optional-restrictions">optional</a>)
703     * @throws NullPointerException if this list contains a null element and the
704     *         specified collection does not permit null elements
705     * (<a href="Collection.html#optional-restrictions">optional</a>),
706     *         or if the specified collection is null
707     * @see Collection#contains(Object)
708     */
709    public boolean retainAll(Collection<?> c) {
710        Objects.requireNonNull(c);
711        return batchRemove(c, true);
712    }
713
714    private boolean batchRemove(Collection<?> c, boolean complement) {
715        final Object[] elementData = this.elementData;
716        int r = 0, w = 0;
717        boolean modified = false;
718        try {
719            for (; r < size; r++)
720                if (c.contains(elementData[r]) == complement)
721                    elementData[w++] = elementData[r];
722        } finally {
723            // Preserve behavioral compatibility with AbstractCollection,
724            // even if c.contains() throws.
725            if (r != size) {
726                System.arraycopy(elementData, r,
727                                 elementData, w,
728                                 size - r);
729                w += size - r;
730            }
731            if (w != size) {
732                // clear to let GC do its work
733                for (int i = w; i < size; i++)
734                    elementData[i] = null;
735                modCount += size - w;
736                size = w;
737                modified = true;
738            }
739        }
740        return modified;
741    }
742
743    /**
744     * Save the state of the <tt>ArrayList</tt> instance to a stream (that
745     * is, serialize it).
746     *
747     * @serialData The length of the array backing the <tt>ArrayList</tt>
748     *             instance is emitted (int), followed by all of its elements
749     *             (each an <tt>Object</tt>) in the proper order.
750     */
751    private void writeObject(java.io.ObjectOutputStream s)
752        throws java.io.IOException{
753        // Write out element count, and any hidden stuff
754        int expectedModCount = modCount;
755        s.defaultWriteObject();
756
757        // Write out size as capacity for behavioural compatibility with clone()
758        s.writeInt(size);
759
760        // Write out all elements in the proper order.
761        for (int i=0; i<size; i++) {
762            s.writeObject(elementData[i]);
763        }
764
765        if (modCount != expectedModCount) {
766            throw new ConcurrentModificationException();
767        }
768    }
769
770    /**
771     * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
772     * deserialize it).
773     */
774    private void readObject(java.io.ObjectInputStream s)
775        throws java.io.IOException, ClassNotFoundException {
776        elementData = EMPTY_ELEMENTDATA;
777
778        // Read in size, and any hidden stuff
779        s.defaultReadObject();
780
781        // Read in capacity
782        s.readInt(); // ignored
783
784        if (size > 0) {
785            // be like clone(), allocate array based upon size not capacity
786            ensureCapacityInternal(size);
787
788            Object[] a = elementData;
789            // Read in all elements in the proper order.
790            for (int i=0; i<size; i++) {
791                a[i] = s.readObject();
792            }
793        }
794    }
795
796    /**
797     * Returns a list iterator over the elements in this list (in proper
798     * sequence), starting at the specified position in the list.
799     * The specified index indicates the first element that would be
800     * returned by an initial call to {@link ListIterator#next next}.
801     * An initial call to {@link ListIterator#previous previous} would
802     * return the element with the specified index minus one.
803     *
804     * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
805     *
806     * @throws IndexOutOfBoundsException {@inheritDoc}
807     */
808    public ListIterator<E> listIterator(int index) {
809        if (index < 0 || index > size)
810            throw new IndexOutOfBoundsException("Index: "+index);
811        return new ListItr(index);
812    }
813
814    /**
815     * Returns a list iterator over the elements in this list (in proper
816     * sequence).
817     *
818     * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
819     *
820     * @see #listIterator(int)
821     */
822    public ListIterator<E> listIterator() {
823        return new ListItr(0);
824    }
825
826    /**
827     * Returns an iterator over the elements in this list in proper sequence.
828     *
829     * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
830     *
831     * @return an iterator over the elements in this list in proper sequence
832     */
833    public Iterator<E> iterator() {
834        return new Itr();
835    }
836
837    /**
838     * An optimized version of AbstractList.Itr
839     */
840    private class Itr implements Iterator<E> {
841        // Android-changed: Add "limit" field to detect end of iteration.
842        // The "limit" of this iterator. This is the size of the list at the time the
843        // iterator was created. Adding & removing elements will invalidate the iteration
844        // anyway (and cause next() to throw) so saving this value will guarantee that the
845        // value of hasNext() remains stable and won't flap between true and false when elements
846        // are added and removed from the list.
847        protected int limit = ArrayList.this.size;
848
849        int cursor;       // index of next element to return
850        int lastRet = -1; // index of last element returned; -1 if no such
851        int expectedModCount = modCount;
852
853        public boolean hasNext() {
854            return cursor < limit;
855        }
856
857        @SuppressWarnings("unchecked")
858        public E next() {
859            if (modCount != expectedModCount)
860                throw new ConcurrentModificationException();
861            int i = cursor;
862            if (i >= limit)
863                throw new NoSuchElementException();
864            Object[] elementData = ArrayList.this.elementData;
865            if (i >= elementData.length)
866                throw new ConcurrentModificationException();
867            cursor = i + 1;
868            return (E) elementData[lastRet = i];
869        }
870
871        public void remove() {
872            if (lastRet < 0)
873                throw new IllegalStateException();
874            if (modCount != expectedModCount)
875                throw new ConcurrentModificationException();
876
877            try {
878                ArrayList.this.remove(lastRet);
879                cursor = lastRet;
880                lastRet = -1;
881                expectedModCount = modCount;
882                limit--;
883            } catch (IndexOutOfBoundsException ex) {
884                throw new ConcurrentModificationException();
885            }
886        }
887
888        @Override
889        @SuppressWarnings("unchecked")
890        public void forEachRemaining(Consumer<? super E> consumer) {
891            Objects.requireNonNull(consumer);
892            final int size = ArrayList.this.size;
893            int i = cursor;
894            if (i >= size) {
895                return;
896            }
897            final Object[] elementData = ArrayList.this.elementData;
898            if (i >= elementData.length) {
899                throw new ConcurrentModificationException();
900            }
901            while (i != size && modCount == expectedModCount) {
902                consumer.accept((E) elementData[i++]);
903            }
904            // update once at end of iteration to reduce heap write traffic
905            cursor = i;
906            lastRet = i - 1;
907
908            if (modCount != expectedModCount)
909                throw new ConcurrentModificationException();
910        }
911    }
912
913    /**
914     * An optimized version of AbstractList.ListItr
915     */
916    private class ListItr extends Itr implements ListIterator<E> {
917        ListItr(int index) {
918            super();
919            cursor = index;
920        }
921
922        public boolean hasPrevious() {
923            return cursor != 0;
924        }
925
926        public int nextIndex() {
927            return cursor;
928        }
929
930        public int previousIndex() {
931            return cursor - 1;
932        }
933
934        @SuppressWarnings("unchecked")
935        public E previous() {
936            if (modCount != expectedModCount)
937                throw new ConcurrentModificationException();
938            int i = cursor - 1;
939            if (i < 0)
940                throw new NoSuchElementException();
941            Object[] elementData = ArrayList.this.elementData;
942            if (i >= elementData.length)
943                throw new ConcurrentModificationException();
944            cursor = i;
945            return (E) elementData[lastRet = i];
946        }
947
948        public void set(E e) {
949            if (lastRet < 0)
950                throw new IllegalStateException();
951            if (modCount != expectedModCount)
952                throw new ConcurrentModificationException();
953
954            try {
955                ArrayList.this.set(lastRet, e);
956            } catch (IndexOutOfBoundsException ex) {
957                throw new ConcurrentModificationException();
958            }
959        }
960
961        public void add(E e) {
962            if (modCount != expectedModCount)
963                throw new ConcurrentModificationException();
964
965            try {
966                int i = cursor;
967                ArrayList.this.add(i, e);
968                cursor = i + 1;
969                lastRet = -1;
970                expectedModCount = modCount;
971                limit++;
972            } catch (IndexOutOfBoundsException ex) {
973                throw new ConcurrentModificationException();
974            }
975        }
976    }
977
978    /**
979     * Returns a view of the portion of this list between the specified
980     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.  (If
981     * {@code fromIndex} and {@code toIndex} are equal, the returned list is
982     * empty.)  The returned list is backed by this list, so non-structural
983     * changes in the returned list are reflected in this list, and vice-versa.
984     * The returned list supports all of the optional list operations.
985     *
986     * <p>This method eliminates the need for explicit range operations (of
987     * the sort that commonly exist for arrays).  Any operation that expects
988     * a list can be used as a range operation by passing a subList view
989     * instead of a whole list.  For example, the following idiom
990     * removes a range of elements from a list:
991     * <pre>
992     *      list.subList(from, to).clear();
993     * </pre>
994     * Similar idioms may be constructed for {@link #indexOf(Object)} and
995     * {@link #lastIndexOf(Object)}, and all of the algorithms in the
996     * {@link Collections} class can be applied to a subList.
997     *
998     * <p>The semantics of the list returned by this method become undefined if
999     * the backing list (i.e., this list) is <i>structurally modified</i> in
1000     * any way other than via the returned list.  (Structural modifications are
1001     * those that change the size of this list, or otherwise perturb it in such
1002     * a fashion that iterations in progress may yield incorrect results.)
1003     *
1004     * @throws IndexOutOfBoundsException {@inheritDoc}
1005     * @throws IllegalArgumentException {@inheritDoc}
1006     */
1007    public List<E> subList(int fromIndex, int toIndex) {
1008        subListRangeCheck(fromIndex, toIndex, size);
1009        return new SubList(this, 0, fromIndex, toIndex);
1010    }
1011
1012    static void subListRangeCheck(int fromIndex, int toIndex, int size) {
1013        if (fromIndex < 0)
1014            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
1015        if (toIndex > size)
1016            throw new IndexOutOfBoundsException("toIndex = " + toIndex);
1017        if (fromIndex > toIndex)
1018            throw new IllegalArgumentException("fromIndex(" + fromIndex +
1019                                               ") > toIndex(" + toIndex + ")");
1020    }
1021
1022    private class SubList extends AbstractList<E> implements RandomAccess {
1023        private final AbstractList<E> parent;
1024        private final int parentOffset;
1025        private final int offset;
1026        int size;
1027
1028        SubList(AbstractList<E> parent,
1029                int offset, int fromIndex, int toIndex) {
1030            this.parent = parent;
1031            this.parentOffset = fromIndex;
1032            this.offset = offset + fromIndex;
1033            this.size = toIndex - fromIndex;
1034            this.modCount = ArrayList.this.modCount;
1035        }
1036
1037        public E set(int index, E e) {
1038            if (index < 0 || index >= this.size)
1039                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1040            if (ArrayList.this.modCount != this.modCount)
1041                throw new ConcurrentModificationException();
1042            E oldValue = (E) ArrayList.this.elementData[offset + index];
1043            ArrayList.this.elementData[offset + index] = e;
1044            return oldValue;
1045        }
1046
1047        public E get(int index) {
1048            if (index < 0 || index >= this.size)
1049              throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1050            if (ArrayList.this.modCount != this.modCount)
1051                throw new ConcurrentModificationException();
1052            return (E) ArrayList.this.elementData[offset + index];
1053        }
1054
1055        public int size() {
1056            if (ArrayList.this.modCount != this.modCount)
1057                throw new ConcurrentModificationException();
1058            return this.size;
1059        }
1060
1061        public void add(int index, E e) {
1062            if (index < 0 || index > this.size)
1063                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1064            if (ArrayList.this.modCount != this.modCount)
1065                throw new ConcurrentModificationException();
1066            parent.add(parentOffset + index, e);
1067            this.modCount = parent.modCount;
1068            this.size++;
1069        }
1070
1071        public E remove(int index) {
1072            if (index < 0 || index >= this.size)
1073                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1074            if (ArrayList.this.modCount != this.modCount)
1075                throw new ConcurrentModificationException();
1076            E result = parent.remove(parentOffset + index);
1077            this.modCount = parent.modCount;
1078            this.size--;
1079            return result;
1080        }
1081
1082        protected void removeRange(int fromIndex, int toIndex) {
1083            if (ArrayList.this.modCount != this.modCount)
1084                throw new ConcurrentModificationException();
1085            parent.removeRange(parentOffset + fromIndex,
1086                               parentOffset + toIndex);
1087            this.modCount = parent.modCount;
1088            this.size -= toIndex - fromIndex;
1089        }
1090
1091        public boolean addAll(Collection<? extends E> c) {
1092            return addAll(this.size, c);
1093        }
1094
1095        public boolean addAll(int index, Collection<? extends E> c) {
1096            if (index < 0 || index > this.size)
1097                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1098            int cSize = c.size();
1099            if (cSize==0)
1100                return false;
1101
1102            if (ArrayList.this.modCount != this.modCount)
1103                throw new ConcurrentModificationException();
1104            parent.addAll(parentOffset + index, c);
1105            this.modCount = parent.modCount;
1106            this.size += cSize;
1107            return true;
1108        }
1109
1110        public Iterator<E> iterator() {
1111            return listIterator();
1112        }
1113
1114        public ListIterator<E> listIterator(final int index) {
1115            if (ArrayList.this.modCount != this.modCount)
1116                throw new ConcurrentModificationException();
1117            if (index < 0 || index > this.size)
1118                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1119            final int offset = this.offset;
1120
1121            return new ListIterator<E>() {
1122                int cursor = index;
1123                int lastRet = -1;
1124                int expectedModCount = ArrayList.this.modCount;
1125
1126                public boolean hasNext() {
1127                    return cursor != SubList.this.size;
1128                }
1129
1130                @SuppressWarnings("unchecked")
1131                public E next() {
1132                    if (expectedModCount != ArrayList.this.modCount)
1133                        throw new ConcurrentModificationException();
1134                    int i = cursor;
1135                    if (i >= SubList.this.size)
1136                        throw new NoSuchElementException();
1137                    Object[] elementData = ArrayList.this.elementData;
1138                    if (offset + i >= elementData.length)
1139                        throw new ConcurrentModificationException();
1140                    cursor = i + 1;
1141                    return (E) elementData[offset + (lastRet = i)];
1142                }
1143
1144                public boolean hasPrevious() {
1145                    return cursor != 0;
1146                }
1147
1148                @SuppressWarnings("unchecked")
1149                public E previous() {
1150                    if (expectedModCount != ArrayList.this.modCount)
1151                        throw new ConcurrentModificationException();
1152                    int i = cursor - 1;
1153                    if (i < 0)
1154                        throw new NoSuchElementException();
1155                    Object[] elementData = ArrayList.this.elementData;
1156                    if (offset + i >= elementData.length)
1157                        throw new ConcurrentModificationException();
1158                    cursor = i;
1159                    return (E) elementData[offset + (lastRet = i)];
1160                }
1161
1162                @SuppressWarnings("unchecked")
1163                public void forEachRemaining(Consumer<? super E> consumer) {
1164                    Objects.requireNonNull(consumer);
1165                    final int size = SubList.this.size;
1166                    int i = cursor;
1167                    if (i >= size) {
1168                        return;
1169                    }
1170                    final Object[] elementData = ArrayList.this.elementData;
1171                    if (offset + i >= elementData.length) {
1172                        throw new ConcurrentModificationException();
1173                    }
1174                    while (i != size && modCount == expectedModCount) {
1175                        consumer.accept((E) elementData[offset + (i++)]);
1176                    }
1177                    // update once at end of iteration to reduce heap write traffic
1178                    lastRet = cursor = i;
1179                    if (expectedModCount != ArrayList.this.modCount)
1180                        throw new ConcurrentModificationException();
1181                }
1182
1183                public int nextIndex() {
1184                    return cursor;
1185                }
1186
1187                public int previousIndex() {
1188                    return cursor - 1;
1189                }
1190
1191                public void remove() {
1192                    if (lastRet < 0)
1193                        throw new IllegalStateException();
1194                    if (expectedModCount != ArrayList.this.modCount)
1195                        throw new ConcurrentModificationException();
1196
1197                    try {
1198                        SubList.this.remove(lastRet);
1199                        cursor = lastRet;
1200                        lastRet = -1;
1201                        expectedModCount = ArrayList.this.modCount;
1202                    } catch (IndexOutOfBoundsException ex) {
1203                        throw new ConcurrentModificationException();
1204                    }
1205                }
1206
1207                public void set(E e) {
1208                    if (lastRet < 0)
1209                        throw new IllegalStateException();
1210                    if (expectedModCount != ArrayList.this.modCount)
1211                        throw new ConcurrentModificationException();
1212
1213                    try {
1214                        ArrayList.this.set(offset + lastRet, e);
1215                    } catch (IndexOutOfBoundsException ex) {
1216                        throw new ConcurrentModificationException();
1217                    }
1218                }
1219
1220                public void add(E e) {
1221                    if (expectedModCount != ArrayList.this.modCount)
1222                        throw new ConcurrentModificationException();
1223
1224                    try {
1225                        int i = cursor;
1226                        SubList.this.add(i, e);
1227                        cursor = i + 1;
1228                        lastRet = -1;
1229                        expectedModCount = ArrayList.this.modCount;
1230                    } catch (IndexOutOfBoundsException ex) {
1231                        throw new ConcurrentModificationException();
1232                    }
1233                }
1234            };
1235        }
1236
1237        public List<E> subList(int fromIndex, int toIndex) {
1238            subListRangeCheck(fromIndex, toIndex, size);
1239            return new SubList(this, offset, fromIndex, toIndex);
1240        }
1241
1242        private String outOfBoundsMsg(int index) {
1243            return "Index: "+index+", Size: "+this.size;
1244        }
1245
1246        public Spliterator<E> spliterator() {
1247            if (modCount != ArrayList.this.modCount)
1248                throw new ConcurrentModificationException();
1249            return new ArrayListSpliterator<E>(ArrayList.this, offset,
1250                                               offset + this.size, this.modCount);
1251        }
1252    }
1253
1254    @Override
1255    public void forEach(Consumer<? super E> action) {
1256        Objects.requireNonNull(action);
1257        final int expectedModCount = modCount;
1258        @SuppressWarnings("unchecked")
1259        final E[] elementData = (E[]) this.elementData;
1260        final int size = this.size;
1261        for (int i=0; modCount == expectedModCount && i < size; i++) {
1262            action.accept(elementData[i]);
1263        }
1264        // Android-note:
1265        // Iterator will not throw a CME if we add something while iterating over the *last* element
1266        // forEach will throw a CME in this case.
1267        if (modCount != expectedModCount) {
1268            throw new ConcurrentModificationException();
1269        }
1270    }
1271
1272    /**
1273     * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
1274     * and <em>fail-fast</em> {@link Spliterator} over the elements in this
1275     * list.
1276     *
1277     * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
1278     * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.
1279     * Overriding implementations should document the reporting of additional
1280     * characteristic values.
1281     *
1282     * @return a {@code Spliterator} over the elements in this list
1283     * @since 1.8
1284     */
1285    @Override
1286    public Spliterator<E> spliterator() {
1287        return new ArrayListSpliterator<>(this, 0, -1, 0);
1288    }
1289
1290    /** Index-based split-by-two, lazily initialized Spliterator */
1291    static final class ArrayListSpliterator<E> implements Spliterator<E> {
1292
1293        /*
1294         * If ArrayLists were immutable, or structurally immutable (no
1295         * adds, removes, etc), we could implement their spliterators
1296         * with Arrays.spliterator. Instead we detect as much
1297         * interference during traversal as practical without
1298         * sacrificing much performance. We rely primarily on
1299         * modCounts. These are not guaranteed to detect concurrency
1300         * violations, and are sometimes overly conservative about
1301         * within-thread interference, but detect enough problems to
1302         * be worthwhile in practice. To carry this out, we (1) lazily
1303         * initialize fence and expectedModCount until the latest
1304         * point that we need to commit to the state we are checking
1305         * against; thus improving precision.  (This doesn't apply to
1306         * SubLists, that create spliterators with current non-lazy
1307         * values).  (2) We perform only a single
1308         * ConcurrentModificationException check at the end of forEach
1309         * (the most performance-sensitive method). When using forEach
1310         * (as opposed to iterators), we can normally only detect
1311         * interference after actions, not before. Further
1312         * CME-triggering checks apply to all other possible
1313         * violations of assumptions for example null or too-small
1314         * elementData array given its size(), that could only have
1315         * occurred due to interference.  This allows the inner loop
1316         * of forEach to run without any further checks, and
1317         * simplifies lambda-resolution. While this does entail a
1318         * number of checks, note that in the common case of
1319         * list.stream().forEach(a), no checks or other computation
1320         * occur anywhere other than inside forEach itself.  The other
1321         * less-often-used methods cannot take advantage of most of
1322         * these streamlinings.
1323         */
1324
1325        private final ArrayList<E> list;
1326        private int index; // current index, modified on advance/split
1327        private int fence; // -1 until used; then one past last index
1328        private int expectedModCount; // initialized when fence set
1329
1330        /** Create new spliterator covering the given  range */
1331        ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
1332                             int expectedModCount) {
1333            this.list = list; // OK if null unless traversed
1334            this.index = origin;
1335            this.fence = fence;
1336            this.expectedModCount = expectedModCount;
1337        }
1338
1339        private int getFence() { // initialize fence to size on first use
1340            int hi; // (a specialized variant appears in method forEach)
1341            ArrayList<E> lst;
1342            if ((hi = fence) < 0) {
1343                if ((lst = list) == null)
1344                    hi = fence = 0;
1345                else {
1346                    expectedModCount = lst.modCount;
1347                    hi = fence = lst.size;
1348                }
1349            }
1350            return hi;
1351        }
1352
1353        public ArrayListSpliterator<E> trySplit() {
1354            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
1355            return (lo >= mid) ? null : // divide range in half unless too small
1356                new ArrayListSpliterator<E>(list, lo, index = mid,
1357                                            expectedModCount);
1358        }
1359
1360        public boolean tryAdvance(Consumer<? super E> action) {
1361            if (action == null)
1362                throw new NullPointerException();
1363            int hi = getFence(), i = index;
1364            if (i < hi) {
1365                index = i + 1;
1366                @SuppressWarnings("unchecked") E e = (E)list.elementData[i];
1367                action.accept(e);
1368                if (list.modCount != expectedModCount)
1369                    throw new ConcurrentModificationException();
1370                return true;
1371            }
1372            return false;
1373        }
1374
1375        public void forEachRemaining(Consumer<? super E> action) {
1376            int i, hi, mc; // hoist accesses and checks from loop
1377            ArrayList<E> lst; Object[] a;
1378            if (action == null)
1379                throw new NullPointerException();
1380            if ((lst = list) != null && (a = lst.elementData) != null) {
1381                if ((hi = fence) < 0) {
1382                    mc = lst.modCount;
1383                    hi = lst.size;
1384                }
1385                else
1386                    mc = expectedModCount;
1387                if ((i = index) >= 0 && (index = hi) <= a.length) {
1388                    for (; i < hi; ++i) {
1389                        @SuppressWarnings("unchecked") E e = (E) a[i];
1390                        action.accept(e);
1391                    }
1392                    if (lst.modCount == mc)
1393                        return;
1394                }
1395            }
1396            throw new ConcurrentModificationException();
1397        }
1398
1399        public long estimateSize() {
1400            return (long) (getFence() - index);
1401        }
1402
1403        public int characteristics() {
1404            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
1405        }
1406    }
1407
1408    @Override
1409    public boolean removeIf(Predicate<? super E> filter) {
1410        Objects.requireNonNull(filter);
1411        // figure out which elements are to be removed
1412        // any exception thrown from the filter predicate at this stage
1413        // will leave the collection unmodified
1414        int removeCount = 0;
1415        final BitSet removeSet = new BitSet(size);
1416        final int expectedModCount = modCount;
1417        final int size = this.size;
1418        for (int i=0; modCount == expectedModCount && i < size; i++) {
1419            @SuppressWarnings("unchecked")
1420            final E element = (E) elementData[i];
1421            if (filter.test(element)) {
1422                removeSet.set(i);
1423                removeCount++;
1424            }
1425        }
1426        if (modCount != expectedModCount) {
1427            throw new ConcurrentModificationException();
1428        }
1429
1430        // shift surviving elements left over the spaces left by removed elements
1431        final boolean anyToRemove = removeCount > 0;
1432        if (anyToRemove) {
1433            final int newSize = size - removeCount;
1434            for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
1435                i = removeSet.nextClearBit(i);
1436                elementData[j] = elementData[i];
1437            }
1438            for (int k=newSize; k < size; k++) {
1439                elementData[k] = null;  // Let gc do its work
1440            }
1441            this.size = newSize;
1442            if (modCount != expectedModCount) {
1443                throw new ConcurrentModificationException();
1444            }
1445            modCount++;
1446        }
1447
1448        return anyToRemove;
1449    }
1450
1451    @Override
1452    @SuppressWarnings("unchecked")
1453    public void replaceAll(UnaryOperator<E> operator) {
1454        Objects.requireNonNull(operator);
1455        final int expectedModCount = modCount;
1456        final int size = this.size;
1457        for (int i=0; modCount == expectedModCount && i < size; i++) {
1458            elementData[i] = operator.apply((E) elementData[i]);
1459        }
1460        if (modCount != expectedModCount) {
1461            throw new ConcurrentModificationException();
1462        }
1463        modCount++;
1464    }
1465
1466    @Override
1467    @SuppressWarnings("unchecked")
1468    public void sort(Comparator<? super E> c) {
1469        final int expectedModCount = modCount;
1470        Arrays.sort((E[]) elementData, 0, size, c);
1471        if (modCount != expectedModCount) {
1472            throw new ConcurrentModificationException();
1473        }
1474        modCount++;
1475    }
1476}
1477