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