ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk8/java/util/ArrayList.java
Revision: 1.2
Committed: Wed Nov 16 19:46:20 2016 UTC (7 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.1: +39 -40 lines
Log Message:
lint

File Contents

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