ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk8/java/util/ArrayList.java
Revision: 1.1
Committed: Tue Nov 15 23:58:20 2016 UTC (7 years, 5 months ago) by jsr166
Branch: MAIN
Log Message:
backport trivial fix for 8169679 to jdk8 ArrayList.java; then re-enable jdk8 ArrayList sublist tests

File Contents

# Content
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 * Resizable-array implementation of the <tt>List</tt> interface. Implements
34 * all optional list operations, and permits all elements, including
35 * <tt>null</tt>. In addition to implementing the <tt>List</tt> interface,
36 * 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 * <tt>Vector</tt>, except that it is unsynchronized.)
39 *
40 * <p>The <tt>size</tt>, <tt>isEmpty</tt>, <tt>get</tt>, <tt>set</tt>,
41 * <tt>iterator</tt>, and <tt>listIterator</tt> operations run in constant
42 * time. The <tt>add</tt> operation runs in <i>amortized constant time</i>,
43 * 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 * to that for the <tt>LinkedList</tt> implementation.
46 *
47 * <p>Each <tt>ArrayList</tt> instance has a <i>capacity</i>. The capacity is
48 * 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 * <p>An application can increase the capacity of an <tt>ArrayList</tt> instance
55 * before adding a large number of elements using the <tt>ensureCapacity</tt>
56 * operation. This may reduce the amount of incremental reallocation.
57 *
58 * <p><strong>Note that this implementation is not synchronized.</strong>
59 * If multiple threads access an <tt>ArrayList</tt> instance concurrently,
60 * 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
106 public class ArrayList<E> extends AbstractList<E>
107 implements List<E>, RandomAccess, Cloneable, java.io.Serializable
108 {
109 private static final long serialVersionUID = 8683452581122892189L;
110
111 /**
112 * Default initial capacity.
113 */
114 private static final int DEFAULT_CAPACITY = 10;
115
116 /**
117 * Shared empty array instance used for empty instances.
118 */
119 private static final Object[] EMPTY_ELEMENTDATA = {};
120
121 /**
122 * Shared empty array instance used for default sized empty instances. We
123 * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
124 * first element is added.
125 */
126 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
127
128 /**
129 * The array buffer into which the elements of the ArrayList are stored.
130 * The capacity of the ArrayList is the length of this array buffer. Any
131 * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
132 * will be expanded to DEFAULT_CAPACITY when the first element is added.
133 */
134 transient Object[] elementData; // non-private to simplify nested class access
135
136 /**
137 * The size of the ArrayList (the number of elements it contains).
138 *
139 * @serial
140 */
141 private int size;
142
143 /**
144 * Constructs an empty list with the specified initial capacity.
145 *
146 * @param initialCapacity the initial capacity of the list
147 * @throws IllegalArgumentException if the specified initial capacity
148 * is negative
149 */
150 public ArrayList(int initialCapacity) {
151 if (initialCapacity > 0) {
152 this.elementData = new Object[initialCapacity];
153 } else if (initialCapacity == 0) {
154 this.elementData = EMPTY_ELEMENTDATA;
155 } else {
156 throw new IllegalArgumentException("Illegal Capacity: "+
157 initialCapacity);
158 }
159 }
160
161 /**
162 * Constructs an empty list with an initial capacity of ten.
163 */
164 public ArrayList() {
165 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
166 }
167
168 /**
169 * Constructs a list containing the elements of the specified
170 * collection, in the order they are returned by the collection's
171 * iterator.
172 *
173 * @param c the collection whose elements are to be placed into this list
174 * @throws NullPointerException if the specified collection is null
175 */
176 public ArrayList(Collection<? extends E> c) {
177 elementData = c.toArray();
178 if ((size = elementData.length) != 0) {
179 // c.toArray might (incorrectly) not return Object[] (see 6260652)
180 if (elementData.getClass() != Object[].class)
181 elementData = Arrays.copyOf(elementData, size, Object[].class);
182 } else {
183 // replace with empty array.
184 this.elementData = EMPTY_ELEMENTDATA;
185 }
186 }
187
188 /**
189 * Trims the capacity of this <tt>ArrayList</tt> instance to be the
190 * list's current size. An application can use this operation to minimize
191 * the storage of an <tt>ArrayList</tt> instance.
192 */
193 public void trimToSize() {
194 modCount++;
195 if (size < elementData.length) {
196 elementData = (size == 0)
197 ? EMPTY_ELEMENTDATA
198 : Arrays.copyOf(elementData, size);
199 }
200 }
201
202 /**
203 * Increases the capacity of this <tt>ArrayList</tt> instance, if
204 * necessary, to ensure that it can hold at least the number of elements
205 * specified by the minimum capacity argument.
206 *
207 * @param minCapacity the desired minimum capacity
208 */
209 public void ensureCapacity(int minCapacity) {
210 int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
211 // any size if not default element table
212 ? 0
213 // larger than default for default empty table. It's already
214 // supposed to be at default size.
215 : DEFAULT_CAPACITY;
216
217 if (minCapacity > minExpand) {
218 ensureExplicitCapacity(minCapacity);
219 }
220 }
221
222 private void ensureCapacityInternal(int minCapacity) {
223 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
224 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
225 }
226
227 ensureExplicitCapacity(minCapacity);
228 }
229
230 private void ensureExplicitCapacity(int minCapacity) {
231 modCount++;
232
233 // overflow-conscious code
234 if (minCapacity - elementData.length > 0)
235 grow(minCapacity);
236 }
237
238 /**
239 * The maximum size of array to allocate.
240 * Some VMs reserve some header words in an array.
241 * Attempts to allocate larger arrays may result in
242 * OutOfMemoryError: Requested array size exceeds VM limit
243 */
244 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
245
246 /**
247 * Increases the capacity to ensure that it can hold at least the
248 * number of elements specified by the minimum capacity argument.
249 *
250 * @param minCapacity the desired minimum capacity
251 */
252 private void grow(int minCapacity) {
253 // overflow-conscious code
254 int oldCapacity = elementData.length;
255 int newCapacity = oldCapacity + (oldCapacity >> 1);
256 if (newCapacity - minCapacity < 0)
257 newCapacity = minCapacity;
258 if (newCapacity - MAX_ARRAY_SIZE > 0)
259 newCapacity = hugeCapacity(minCapacity);
260 // minCapacity is usually close to size, so this is a win:
261 elementData = Arrays.copyOf(elementData, newCapacity);
262 }
263
264 private static int hugeCapacity(int minCapacity) {
265 if (minCapacity < 0) // overflow
266 throw new OutOfMemoryError();
267 return (minCapacity > MAX_ARRAY_SIZE) ?
268 Integer.MAX_VALUE :
269 MAX_ARRAY_SIZE;
270 }
271
272 /**
273 * Returns the number of elements in this list.
274 *
275 * @return the number of elements in this list
276 */
277 public int size() {
278 return size;
279 }
280
281 /**
282 * Returns <tt>true</tt> if this list contains no elements.
283 *
284 * @return <tt>true</tt> if this list contains no elements
285 */
286 public boolean isEmpty() {
287 return size == 0;
288 }
289
290 /**
291 * Returns <tt>true</tt> if this list contains the specified element.
292 * More formally, returns <tt>true</tt> if and only if this list contains
293 * at least one element <tt>e</tt> such that
294 * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
295 *
296 * @param o element whose presence in this list is to be tested
297 * @return <tt>true</tt> if this list contains the specified element
298 */
299 public boolean contains(Object o) {
300 return indexOf(o) >= 0;
301 }
302
303 /**
304 * Returns the index of the first occurrence of the specified element
305 * in this list, or -1 if this list does not contain the element.
306 * More formally, returns the lowest index <tt>i</tt> such that
307 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
308 * or -1 if there is no such index.
309 */
310 public int indexOf(Object o) {
311 if (o == null) {
312 for (int i = 0; i < size; i++)
313 if (elementData[i]==null)
314 return i;
315 } else {
316 for (int i = 0; i < size; i++)
317 if (o.equals(elementData[i]))
318 return i;
319 }
320 return -1;
321 }
322
323 /**
324 * Returns the index of the last occurrence of the specified element
325 * in this list, or -1 if this list does not contain the element.
326 * More formally, returns the highest index <tt>i</tt> such that
327 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
328 * or -1 if there is no such index.
329 */
330 public int lastIndexOf(Object o) {
331 if (o == null) {
332 for (int i = size-1; i >= 0; i--)
333 if (elementData[i]==null)
334 return i;
335 } else {
336 for (int i = size-1; i >= 0; i--)
337 if (o.equals(elementData[i]))
338 return i;
339 }
340 return -1;
341 }
342
343 /**
344 * Returns a shallow copy of this <tt>ArrayList</tt> instance. (The
345 * elements themselves are not copied.)
346 *
347 * @return a clone of this <tt>ArrayList</tt> instance
348 */
349 public Object clone() {
350 try {
351 ArrayList<?> v = (ArrayList<?>) super.clone();
352 v.elementData = Arrays.copyOf(elementData, size);
353 v.modCount = 0;
354 return v;
355 } catch (CloneNotSupportedException e) {
356 // this shouldn't happen, since we are Cloneable
357 throw new InternalError(e);
358 }
359 }
360
361 /**
362 * Returns an array containing all of the elements in this list
363 * in proper sequence (from first to last element).
364 *
365 * <p>The returned array will be "safe" in that no references to it are
366 * maintained by this list. (In other words, this method must allocate
367 * a new array). The caller is thus free to modify the returned array.
368 *
369 * <p>This method acts as bridge between array-based and collection-based
370 * APIs.
371 *
372 * @return an array containing all of the elements in this list in
373 * proper sequence
374 */
375 public Object[] toArray() {
376 return Arrays.copyOf(elementData, size);
377 }
378
379 /**
380 * Returns an array containing all of the elements in this list in proper
381 * sequence (from first to last element); the runtime type of the returned
382 * array is that of the specified array. If the list fits in the
383 * specified array, it is returned therein. Otherwise, a new array is
384 * allocated with the runtime type of the specified array and the size of
385 * this list.
386 *
387 * <p>If the list fits in the specified array with room to spare
388 * (i.e., the array has more elements than the list), the element in
389 * the array immediately following the end of the collection is set to
390 * <tt>null</tt>. (This is useful in determining the length of the
391 * list <i>only</i> if the caller knows that the list does not contain
392 * any null elements.)
393 *
394 * @param a the array into which the elements of the list are to
395 * be stored, if it is big enough; otherwise, a new array of the
396 * same runtime type is allocated for this purpose.
397 * @return an array containing the elements of the list
398 * @throws ArrayStoreException if the runtime type of the specified array
399 * is not a supertype of the runtime type of every element in
400 * this list
401 * @throws NullPointerException if the specified array is null
402 */
403 @SuppressWarnings("unchecked")
404 public <T> T[] toArray(T[] a) {
405 if (a.length < size)
406 // Make a new array of a's runtime type, but my contents:
407 return (T[]) Arrays.copyOf(elementData, size, a.getClass());
408 System.arraycopy(elementData, 0, a, 0, size);
409 if (a.length > size)
410 a[size] = null;
411 return a;
412 }
413
414 // Positional Access Operations
415
416 @SuppressWarnings("unchecked")
417 E elementData(int index) {
418 return (E) elementData[index];
419 }
420
421 /**
422 * Returns the element at the specified position in this list.
423 *
424 * @param index index of the element to return
425 * @return the element at the specified position in this list
426 * @throws IndexOutOfBoundsException {@inheritDoc}
427 */
428 public E get(int index) {
429 rangeCheck(index);
430
431 return elementData(index);
432 }
433
434 /**
435 * Replaces the element at the specified position in this list with
436 * the specified element.
437 *
438 * @param index index of the element to replace
439 * @param element element to be stored at the specified position
440 * @return the element previously at the specified position
441 * @throws IndexOutOfBoundsException {@inheritDoc}
442 */
443 public E set(int index, E element) {
444 rangeCheck(index);
445
446 E oldValue = elementData(index);
447 elementData[index] = element;
448 return oldValue;
449 }
450
451 /**
452 * Appends the specified element to the end of this list.
453 *
454 * @param e element to be appended to this list
455 * @return <tt>true</tt> (as specified by {@link Collection#add})
456 */
457 public boolean add(E e) {
458 ensureCapacityInternal(size + 1); // Increments modCount!!
459 elementData[size++] = e;
460 return true;
461 }
462
463 /**
464 * Inserts the specified element at the specified position in this
465 * list. Shifts the element currently at that position (if any) and
466 * any subsequent elements to the right (adds one to their indices).
467 *
468 * @param index index at which the specified element is to be inserted
469 * @param element element to be inserted
470 * @throws IndexOutOfBoundsException {@inheritDoc}
471 */
472 public void add(int index, E element) {
473 rangeCheckForAdd(index);
474
475 ensureCapacityInternal(size + 1); // Increments modCount!!
476 System.arraycopy(elementData, index, elementData, index + 1,
477 size - index);
478 elementData[index] = element;
479 size++;
480 }
481
482 /**
483 * Removes the element at the specified position in this list.
484 * Shifts any subsequent elements to the left (subtracts one from their
485 * indices).
486 *
487 * @param index the index of the element to be removed
488 * @return the element that was removed from the list
489 * @throws IndexOutOfBoundsException {@inheritDoc}
490 */
491 public E remove(int index) {
492 rangeCheck(index);
493
494 modCount++;
495 E oldValue = elementData(index);
496
497 int numMoved = size - index - 1;
498 if (numMoved > 0)
499 System.arraycopy(elementData, index+1, elementData, index,
500 numMoved);
501 elementData[--size] = null; // clear to let GC do its work
502
503 return oldValue;
504 }
505
506 /**
507 * Removes the first occurrence of the specified element from this list,
508 * if it is present. If the list does not contain the element, it is
509 * unchanged. More formally, removes the element with the lowest index
510 * <tt>i</tt> such that
511 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
512 * (if such an element exists). Returns <tt>true</tt> if this list
513 * contained the specified element (or equivalently, if this list
514 * changed as a result of the call).
515 *
516 * @param o element to be removed from this list, if present
517 * @return <tt>true</tt> if this list contained the specified element
518 */
519 public boolean remove(Object o) {
520 if (o == null) {
521 for (int index = 0; index < size; index++)
522 if (elementData[index] == null) {
523 fastRemove(index);
524 return true;
525 }
526 } else {
527 for (int index = 0; index < size; index++)
528 if (o.equals(elementData[index])) {
529 fastRemove(index);
530 return true;
531 }
532 }
533 return false;
534 }
535
536 /*
537 * Private remove method that skips bounds checking and does not
538 * return the value removed.
539 */
540 private void fastRemove(int index) {
541 modCount++;
542 int numMoved = size - index - 1;
543 if (numMoved > 0)
544 System.arraycopy(elementData, index+1, elementData, index,
545 numMoved);
546 elementData[--size] = null; // clear to let GC do its work
547 }
548
549 /**
550 * Removes all of the elements from this list. The list will
551 * be empty after this call returns.
552 */
553 public void clear() {
554 modCount++;
555
556 // clear to let GC do its work
557 for (int i = 0; i < size; i++)
558 elementData[i] = null;
559
560 size = 0;
561 }
562
563 /**
564 * Appends all of the elements in the specified collection to the end of
565 * this list, in the order that they are returned by the
566 * specified collection's Iterator. The behavior of this operation is
567 * undefined if the specified collection is modified while the operation
568 * is in progress. (This implies that the behavior of this call is
569 * undefined if the specified collection is this list, and this
570 * list is nonempty.)
571 *
572 * @param c collection containing elements to be added to this list
573 * @return <tt>true</tt> if this list changed as a result of the call
574 * @throws NullPointerException if the specified collection is null
575 */
576 public boolean addAll(Collection<? extends E> c) {
577 Object[] a = c.toArray();
578 int numNew = a.length;
579 ensureCapacityInternal(size + numNew); // Increments modCount
580 System.arraycopy(a, 0, elementData, size, numNew);
581 size += numNew;
582 return numNew != 0;
583 }
584
585 /**
586 * Inserts all of the elements in the specified collection into this
587 * list, starting at the specified position. Shifts the element
588 * currently at that position (if any) and any subsequent elements to
589 * the right (increases their indices). The new elements will appear
590 * in the list in the order that they are returned by the
591 * specified collection's iterator.
592 *
593 * @param index index at which to insert the first element from the
594 * specified collection
595 * @param c collection containing elements to be added to this list
596 * @return <tt>true</tt> if this list changed as a result of the call
597 * @throws IndexOutOfBoundsException {@inheritDoc}
598 * @throws NullPointerException if the specified collection is null
599 */
600 public boolean addAll(int index, Collection<? extends E> c) {
601 rangeCheckForAdd(index);
602
603 Object[] a = c.toArray();
604 int numNew = a.length;
605 ensureCapacityInternal(size + numNew); // Increments modCount
606
607 int numMoved = size - index;
608 if (numMoved > 0)
609 System.arraycopy(elementData, index, elementData, index + numNew,
610 numMoved);
611
612 System.arraycopy(a, 0, elementData, index, numNew);
613 size += numNew;
614 return numNew != 0;
615 }
616
617 /**
618 * Removes from this list all of the elements whose index is between
619 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
620 * Shifts any succeeding elements to the left (reduces their index).
621 * This call shortens the list by {@code (toIndex - fromIndex)} elements.
622 * (If {@code toIndex==fromIndex}, this operation has no effect.)
623 *
624 * @throws IndexOutOfBoundsException if {@code fromIndex} or
625 * {@code toIndex} is out of range
626 * ({@code fromIndex < 0 ||
627 * fromIndex >= size() ||
628 * toIndex > size() ||
629 * toIndex < fromIndex})
630 */
631 protected void removeRange(int fromIndex, int toIndex) {
632 modCount++;
633 int numMoved = size - toIndex;
634 System.arraycopy(elementData, toIndex, elementData, fromIndex,
635 numMoved);
636
637 // clear to let GC do its work
638 int newSize = size - (toIndex-fromIndex);
639 for (int i = newSize; i < size; i++) {
640 elementData[i] = null;
641 }
642 size = newSize;
643 }
644
645 /**
646 * Checks if the given index is in range. If not, throws an appropriate
647 * runtime exception. This method does *not* check if the index is
648 * negative: It is always used immediately prior to an array access,
649 * which throws an ArrayIndexOutOfBoundsException if index is negative.
650 */
651 private void rangeCheck(int index) {
652 if (index >= size)
653 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
654 }
655
656 /**
657 * A version of rangeCheck used by add and addAll.
658 */
659 private void rangeCheckForAdd(int index) {
660 if (index > size || index < 0)
661 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
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 int cursor; // index of next element to return
842 int lastRet = -1; // index of last element returned; -1 if no such
843 int expectedModCount = modCount;
844
845 Itr() {}
846
847 public boolean hasNext() {
848 return cursor != size;
849 }
850
851 @SuppressWarnings("unchecked")
852 public E next() {
853 checkForComodification();
854 int i = cursor;
855 if (i >= size)
856 throw new NoSuchElementException();
857 Object[] elementData = ArrayList.this.elementData;
858 if (i >= elementData.length)
859 throw new ConcurrentModificationException();
860 cursor = i + 1;
861 return (E) elementData[lastRet = i];
862 }
863
864 public void remove() {
865 if (lastRet < 0)
866 throw new IllegalStateException();
867 checkForComodification();
868
869 try {
870 ArrayList.this.remove(lastRet);
871 cursor = lastRet;
872 lastRet = -1;
873 expectedModCount = modCount;
874 } catch (IndexOutOfBoundsException ex) {
875 throw new ConcurrentModificationException();
876 }
877 }
878
879 @Override
880 @SuppressWarnings("unchecked")
881 public void forEachRemaining(Consumer<? super E> consumer) {
882 Objects.requireNonNull(consumer);
883 final int size = ArrayList.this.size;
884 int i = cursor;
885 if (i >= size) {
886 return;
887 }
888 final Object[] elementData = ArrayList.this.elementData;
889 if (i >= elementData.length) {
890 throw new ConcurrentModificationException();
891 }
892 while (i != size && modCount == expectedModCount) {
893 consumer.accept((E) elementData[i++]);
894 }
895 // update once at end of iteration to reduce heap write traffic
896 cursor = i;
897 lastRet = i - 1;
898 checkForComodification();
899 }
900
901 final void checkForComodification() {
902 if (modCount != expectedModCount)
903 throw new ConcurrentModificationException();
904 }
905 }
906
907 /**
908 * An optimized version of AbstractList.ListItr
909 */
910 private class ListItr extends Itr implements ListIterator<E> {
911 ListItr(int index) {
912 super();
913 cursor = index;
914 }
915
916 public boolean hasPrevious() {
917 return cursor != 0;
918 }
919
920 public int nextIndex() {
921 return cursor;
922 }
923
924 public int previousIndex() {
925 return cursor - 1;
926 }
927
928 @SuppressWarnings("unchecked")
929 public E previous() {
930 checkForComodification();
931 int i = cursor - 1;
932 if (i < 0)
933 throw new NoSuchElementException();
934 Object[] elementData = ArrayList.this.elementData;
935 if (i >= elementData.length)
936 throw new ConcurrentModificationException();
937 cursor = i;
938 return (E) elementData[lastRet = i];
939 }
940
941 public void set(E e) {
942 if (lastRet < 0)
943 throw new IllegalStateException();
944 checkForComodification();
945
946 try {
947 ArrayList.this.set(lastRet, e);
948 } catch (IndexOutOfBoundsException ex) {
949 throw new ConcurrentModificationException();
950 }
951 }
952
953 public void add(E e) {
954 checkForComodification();
955
956 try {
957 int i = cursor;
958 ArrayList.this.add(i, e);
959 cursor = i + 1;
960 lastRet = -1;
961 expectedModCount = modCount;
962 } catch (IndexOutOfBoundsException ex) {
963 throw new ConcurrentModificationException();
964 }
965 }
966 }
967
968 /**
969 * Returns a view of the portion of this list between the specified
970 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If
971 * {@code fromIndex} and {@code toIndex} are equal, the returned list is
972 * empty.) The returned list is backed by this list, so non-structural
973 * changes in the returned list are reflected in this list, and vice-versa.
974 * The returned list supports all of the optional list operations.
975 *
976 * <p>This method eliminates the need for explicit range operations (of
977 * the sort that commonly exist for arrays). Any operation that expects
978 * a list can be used as a range operation by passing a subList view
979 * instead of a whole list. For example, the following idiom
980 * removes a range of elements from a list:
981 * <pre>
982 * list.subList(from, to).clear();
983 * </pre>
984 * Similar idioms may be constructed for {@link #indexOf(Object)} and
985 * {@link #lastIndexOf(Object)}, and all of the algorithms in the
986 * {@link Collections} class can be applied to a subList.
987 *
988 * <p>The semantics of the list returned by this method become undefined if
989 * the backing list (i.e., this list) is <i>structurally modified</i> in
990 * any way other than via the returned list. (Structural modifications are
991 * those that change the size of this list, or otherwise perturb it in such
992 * a fashion that iterations in progress may yield incorrect results.)
993 *
994 * @throws IndexOutOfBoundsException {@inheritDoc}
995 * @throws IllegalArgumentException {@inheritDoc}
996 */
997 public List<E> subList(int fromIndex, int toIndex) {
998 subListRangeCheck(fromIndex, toIndex, size);
999 return new SubList(this, 0, fromIndex, toIndex);
1000 }
1001
1002 static void subListRangeCheck(int fromIndex, int toIndex, int size) {
1003 if (fromIndex < 0)
1004 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
1005 if (toIndex > size)
1006 throw new IndexOutOfBoundsException("toIndex = " + toIndex);
1007 if (fromIndex > toIndex)
1008 throw new IllegalArgumentException("fromIndex(" + fromIndex +
1009 ") > toIndex(" + toIndex + ")");
1010 }
1011
1012 private class SubList extends AbstractList<E> implements RandomAccess {
1013 private final AbstractList<E> parent;
1014 private final int parentOffset;
1015 private final int offset;
1016 int size;
1017
1018 SubList(AbstractList<E> parent,
1019 int offset, int fromIndex, int toIndex) {
1020 this.parent = parent;
1021 this.parentOffset = fromIndex;
1022 this.offset = offset + fromIndex;
1023 this.size = toIndex - fromIndex;
1024 this.modCount = ArrayList.this.modCount;
1025 }
1026
1027 public E set(int index, E e) {
1028 rangeCheck(index);
1029 checkForComodification();
1030 E oldValue = ArrayList.this.elementData(offset + index);
1031 ArrayList.this.elementData[offset + index] = e;
1032 return oldValue;
1033 }
1034
1035 public E get(int index) {
1036 rangeCheck(index);
1037 checkForComodification();
1038 return ArrayList.this.elementData(offset + index);
1039 }
1040
1041 public int size() {
1042 checkForComodification();
1043 return this.size;
1044 }
1045
1046 public void add(int index, E e) {
1047 rangeCheckForAdd(index);
1048 checkForComodification();
1049 parent.add(parentOffset + index, e);
1050 this.modCount = parent.modCount;
1051 this.size++;
1052 }
1053
1054 public E remove(int index) {
1055 rangeCheck(index);
1056 checkForComodification();
1057 E result = parent.remove(parentOffset + index);
1058 this.modCount = parent.modCount;
1059 this.size--;
1060 return result;
1061 }
1062
1063 protected void removeRange(int fromIndex, int toIndex) {
1064 checkForComodification();
1065 parent.removeRange(parentOffset + fromIndex,
1066 parentOffset + toIndex);
1067 this.modCount = parent.modCount;
1068 this.size -= toIndex - fromIndex;
1069 }
1070
1071 public boolean addAll(Collection<? extends E> c) {
1072 return addAll(this.size, c);
1073 }
1074
1075 public boolean addAll(int index, Collection<? extends E> c) {
1076 rangeCheckForAdd(index);
1077 int cSize = c.size();
1078 if (cSize==0)
1079 return false;
1080
1081 checkForComodification();
1082 parent.addAll(parentOffset + index, c);
1083 this.modCount = parent.modCount;
1084 this.size += cSize;
1085 return true;
1086 }
1087
1088 public Iterator<E> iterator() {
1089 return listIterator();
1090 }
1091
1092 public ListIterator<E> listIterator(final int index) {
1093 checkForComodification();
1094 rangeCheckForAdd(index);
1095 final int offset = this.offset;
1096
1097 return new ListIterator<E>() {
1098 int cursor = index;
1099 int lastRet = -1;
1100 int expectedModCount = ArrayList.this.modCount;
1101
1102 public boolean hasNext() {
1103 return cursor != SubList.this.size;
1104 }
1105
1106 @SuppressWarnings("unchecked")
1107 public E next() {
1108 checkForComodification();
1109 int i = cursor;
1110 if (i >= SubList.this.size)
1111 throw new NoSuchElementException();
1112 Object[] elementData = ArrayList.this.elementData;
1113 if (offset + i >= elementData.length)
1114 throw new ConcurrentModificationException();
1115 cursor = i + 1;
1116 return (E) elementData[offset + (lastRet = i)];
1117 }
1118
1119 public boolean hasPrevious() {
1120 return cursor != 0;
1121 }
1122
1123 @SuppressWarnings("unchecked")
1124 public E previous() {
1125 checkForComodification();
1126 int i = cursor - 1;
1127 if (i < 0)
1128 throw new NoSuchElementException();
1129 Object[] elementData = ArrayList.this.elementData;
1130 if (offset + i >= elementData.length)
1131 throw new ConcurrentModificationException();
1132 cursor = i;
1133 return (E) elementData[offset + (lastRet = i)];
1134 }
1135
1136 @SuppressWarnings("unchecked")
1137 public void forEachRemaining(Consumer<? super E> consumer) {
1138 Objects.requireNonNull(consumer);
1139 final int size = SubList.this.size;
1140 int i = cursor;
1141 if (i >= size) {
1142 return;
1143 }
1144 final Object[] elementData = ArrayList.this.elementData;
1145 if (offset + i >= elementData.length) {
1146 throw new ConcurrentModificationException();
1147 }
1148 while (i != size && modCount == expectedModCount) {
1149 consumer.accept((E) elementData[offset + (i++)]);
1150 }
1151 // update once at end of iteration to reduce heap write traffic
1152 cursor = i;
1153 lastRet = i - 1;
1154 checkForComodification();
1155 }
1156
1157 public int nextIndex() {
1158 return cursor;
1159 }
1160
1161 public int previousIndex() {
1162 return cursor - 1;
1163 }
1164
1165 public void remove() {
1166 if (lastRet < 0)
1167 throw new IllegalStateException();
1168 checkForComodification();
1169
1170 try {
1171 SubList.this.remove(lastRet);
1172 cursor = lastRet;
1173 lastRet = -1;
1174 expectedModCount = ArrayList.this.modCount;
1175 } catch (IndexOutOfBoundsException ex) {
1176 throw new ConcurrentModificationException();
1177 }
1178 }
1179
1180 public void set(E e) {
1181 if (lastRet < 0)
1182 throw new IllegalStateException();
1183 checkForComodification();
1184
1185 try {
1186 ArrayList.this.set(offset + lastRet, e);
1187 } catch (IndexOutOfBoundsException ex) {
1188 throw new ConcurrentModificationException();
1189 }
1190 }
1191
1192 public void add(E e) {
1193 checkForComodification();
1194
1195 try {
1196 int i = cursor;
1197 SubList.this.add(i, e);
1198 cursor = i + 1;
1199 lastRet = -1;
1200 expectedModCount = ArrayList.this.modCount;
1201 } catch (IndexOutOfBoundsException ex) {
1202 throw new ConcurrentModificationException();
1203 }
1204 }
1205
1206 final void checkForComodification() {
1207 if (expectedModCount != ArrayList.this.modCount)
1208 throw new ConcurrentModificationException();
1209 }
1210 };
1211 }
1212
1213 public List<E> subList(int fromIndex, int toIndex) {
1214 subListRangeCheck(fromIndex, toIndex, size);
1215 return new SubList(this, offset, fromIndex, toIndex);
1216 }
1217
1218 private void rangeCheck(int index) {
1219 if (index < 0 || index >= this.size)
1220 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1221 }
1222
1223 private void rangeCheckForAdd(int index) {
1224 if (index < 0 || index > this.size)
1225 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1226 }
1227
1228 private String outOfBoundsMsg(int index) {
1229 return "Index: "+index+", Size: "+this.size;
1230 }
1231
1232 private void checkForComodification() {
1233 if (ArrayList.this.modCount != this.modCount)
1234 throw new ConcurrentModificationException();
1235 }
1236
1237 public Spliterator<E> spliterator() {
1238 checkForComodification();
1239 return new ArrayListSpliterator<E>(ArrayList.this, offset,
1240 offset + this.size, this.modCount);
1241 }
1242 }
1243
1244 @Override
1245 public void forEach(Consumer<? super E> action) {
1246 Objects.requireNonNull(action);
1247 final int expectedModCount = modCount;
1248 @SuppressWarnings("unchecked")
1249 final E[] elementData = (E[]) this.elementData;
1250 final int size = this.size;
1251 for (int i=0; modCount == expectedModCount && i < size; i++) {
1252 action.accept(elementData[i]);
1253 }
1254 if (modCount != expectedModCount) {
1255 throw new ConcurrentModificationException();
1256 }
1257 }
1258
1259 /**
1260 * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
1261 * and <em>fail-fast</em> {@link Spliterator} over the elements in this
1262 * list.
1263 *
1264 * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
1265 * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.
1266 * Overriding implementations should document the reporting of additional
1267 * characteristic values.
1268 *
1269 * @return a {@code Spliterator} over the elements in this list
1270 * @since 1.8
1271 */
1272 @Override
1273 public Spliterator<E> spliterator() {
1274 return new ArrayListSpliterator<>(this, 0, -1, 0);
1275 }
1276
1277 /** Index-based split-by-two, lazily initialized Spliterator */
1278 static final class ArrayListSpliterator<E> implements Spliterator<E> {
1279
1280 /*
1281 * If ArrayLists were immutable, or structurally immutable (no
1282 * adds, removes, etc), we could implement their spliterators
1283 * with Arrays.spliterator. Instead we detect as much
1284 * interference during traversal as practical without
1285 * sacrificing much performance. We rely primarily on
1286 * modCounts. These are not guaranteed to detect concurrency
1287 * violations, and are sometimes overly conservative about
1288 * within-thread interference, but detect enough problems to
1289 * be worthwhile in practice. To carry this out, we (1) lazily
1290 * initialize fence and expectedModCount until the latest
1291 * point that we need to commit to the state we are checking
1292 * against; thus improving precision. (This doesn't apply to
1293 * SubLists, that create spliterators with current non-lazy
1294 * values). (2) We perform only a single
1295 * ConcurrentModificationException check at the end of forEach
1296 * (the most performance-sensitive method). When using forEach
1297 * (as opposed to iterators), we can normally only detect
1298 * interference after actions, not before. Further
1299 * CME-triggering checks apply to all other possible
1300 * violations of assumptions for example null or too-small
1301 * elementData array given its size(), that could only have
1302 * occurred due to interference. This allows the inner loop
1303 * of forEach to run without any further checks, and
1304 * simplifies lambda-resolution. While this does entail a
1305 * number of checks, note that in the common case of
1306 * list.stream().forEach(a), no checks or other computation
1307 * occur anywhere other than inside forEach itself. The other
1308 * less-often-used methods cannot take advantage of most of
1309 * these streamlinings.
1310 */
1311
1312 private final ArrayList<E> list;
1313 private int index; // current index, modified on advance/split
1314 private int fence; // -1 until used; then one past last index
1315 private int expectedModCount; // initialized when fence set
1316
1317 /** Create new spliterator covering the given range */
1318 ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
1319 int expectedModCount) {
1320 this.list = list; // OK if null unless traversed
1321 this.index = origin;
1322 this.fence = fence;
1323 this.expectedModCount = expectedModCount;
1324 }
1325
1326 private int getFence() { // initialize fence to size on first use
1327 int hi; // (a specialized variant appears in method forEach)
1328 ArrayList<E> lst;
1329 if ((hi = fence) < 0) {
1330 if ((lst = list) == null)
1331 hi = fence = 0;
1332 else {
1333 expectedModCount = lst.modCount;
1334 hi = fence = lst.size;
1335 }
1336 }
1337 return hi;
1338 }
1339
1340 public ArrayListSpliterator<E> trySplit() {
1341 int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
1342 return (lo >= mid) ? null : // divide range in half unless too small
1343 new ArrayListSpliterator<E>(list, lo, index = mid,
1344 expectedModCount);
1345 }
1346
1347 public boolean tryAdvance(Consumer<? super E> action) {
1348 if (action == null)
1349 throw new NullPointerException();
1350 int hi = getFence(), i = index;
1351 if (i < hi) {
1352 index = i + 1;
1353 @SuppressWarnings("unchecked") E e = (E)list.elementData[i];
1354 action.accept(e);
1355 if (list.modCount != expectedModCount)
1356 throw new ConcurrentModificationException();
1357 return true;
1358 }
1359 return false;
1360 }
1361
1362 public void forEachRemaining(Consumer<? super E> action) {
1363 int i, hi, mc; // hoist accesses and checks from loop
1364 ArrayList<E> lst; Object[] a;
1365 if (action == null)
1366 throw new NullPointerException();
1367 if ((lst = list) != null && (a = lst.elementData) != null) {
1368 if ((hi = fence) < 0) {
1369 mc = lst.modCount;
1370 hi = lst.size;
1371 }
1372 else
1373 mc = expectedModCount;
1374 if ((i = index) >= 0 && (index = hi) <= a.length) {
1375 for (; i < hi; ++i) {
1376 @SuppressWarnings("unchecked") E e = (E) a[i];
1377 action.accept(e);
1378 }
1379 if (lst.modCount == mc)
1380 return;
1381 }
1382 }
1383 throw new ConcurrentModificationException();
1384 }
1385
1386 public long estimateSize() {
1387 return (long) (getFence() - index);
1388 }
1389
1390 public int characteristics() {
1391 return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
1392 }
1393 }
1394
1395 @Override
1396 public boolean removeIf(Predicate<? super E> filter) {
1397 Objects.requireNonNull(filter);
1398 // figure out which elements are to be removed
1399 // any exception thrown from the filter predicate at this stage
1400 // will leave the collection unmodified
1401 int removeCount = 0;
1402 final BitSet removeSet = new BitSet(size);
1403 final int expectedModCount = modCount;
1404 final int size = this.size;
1405 for (int i=0; modCount == expectedModCount && i < size; i++) {
1406 @SuppressWarnings("unchecked")
1407 final E element = (E) elementData[i];
1408 if (filter.test(element)) {
1409 removeSet.set(i);
1410 removeCount++;
1411 }
1412 }
1413 if (modCount != expectedModCount) {
1414 throw new ConcurrentModificationException();
1415 }
1416
1417 // shift surviving elements left over the spaces left by removed elements
1418 final boolean anyToRemove = removeCount > 0;
1419 if (anyToRemove) {
1420 final int newSize = size - removeCount;
1421 for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
1422 i = removeSet.nextClearBit(i);
1423 elementData[j] = elementData[i];
1424 }
1425 for (int k=newSize; k < size; k++) {
1426 elementData[k] = null; // Let gc do its work
1427 }
1428 this.size = newSize;
1429 if (modCount != expectedModCount) {
1430 throw new ConcurrentModificationException();
1431 }
1432 modCount++;
1433 }
1434
1435 return anyToRemove;
1436 }
1437
1438 @Override
1439 @SuppressWarnings("unchecked")
1440 public void replaceAll(UnaryOperator<E> operator) {
1441 Objects.requireNonNull(operator);
1442 final int expectedModCount = modCount;
1443 final int size = this.size;
1444 for (int i=0; modCount == expectedModCount && i < size; i++) {
1445 elementData[i] = operator.apply((E) elementData[i]);
1446 }
1447 if (modCount != expectedModCount) {
1448 throw new ConcurrentModificationException();
1449 }
1450 modCount++;
1451 }
1452
1453 @Override
1454 @SuppressWarnings("unchecked")
1455 public void sort(Comparator<? super E> c) {
1456 final int expectedModCount = modCount;
1457 Arrays.sort((E[]) elementData, 0, size, c);
1458 if (modCount != expectedModCount) {
1459 throw new ConcurrentModificationException();
1460 }
1461 modCount++;
1462 }
1463 }