· 6 years ago · Oct 30, 2019, 04:44 PM
1/*
2 * Copyright (c) 1997, 2013, 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;
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
106public 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 ? e==null : 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 ? get(i)==null : 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 ? get(i)==null : 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 ? get(i)==null : 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 public boolean hasNext() {
846 return cursor != size;
847 }
848
849 @SuppressWarnings("unchecked")
850 public E next() {
851 checkForComodification();
852 int i = cursor;
853 if (i >= size)
854 throw new NoSuchElementException();
855 Object[] elementData = ArrayList.this.elementData;
856 if (i >= elementData.length)
857 throw new ConcurrentModificationException();
858 cursor = i + 1;
859 return (E) elementData[lastRet = i];
860 }
861
862 public void remove() {
863 if (lastRet < 0)
864 throw new IllegalStateException();
865 checkForComodification();
866
867 try {
868 ArrayList.this.remove(lastRet);
869 cursor = lastRet;
870 lastRet = -1;
871 expectedModCount = modCount;
872 } catch (IndexOutOfBoundsException ex) {
873 throw new ConcurrentModificationException();
874 }
875 }
876
877 @Override
878 @SuppressWarnings("unchecked")
879 public void forEachRemaining(Consumer<? super E> consumer) {
880 Objects.requireNonNull(consumer);
881 final int size = ArrayList.this.size;
882 int i = cursor;
883 if (i >= size) {
884 return;
885 }
886 final Object[] elementData = ArrayList.this.elementData;
887 if (i >= elementData.length) {
888 throw new ConcurrentModificationException();
889 }
890 while (i != size && modCount == expectedModCount) {
891 consumer.accept((E) elementData[i++]);
892 }
893 // update once at end of iteration to reduce heap write traffic
894 cursor = i;
895 lastRet = i - 1;
896 checkForComodification();
897 }
898
899 final void checkForComodification() {
900 if (modCount != expectedModCount)
901 throw new ConcurrentModificationException();
902 }
903 }
904
905 /**
906 * An optimized version of AbstractList.ListItr
907 */
908 private class ListItr extends Itr implements ListIterator<E> {
909 ListItr(int index) {
910 super();
911 cursor = index;
912 }
913
914 public boolean hasPrevious() {
915 return cursor != 0;
916 }
917
918 public int nextIndex() {
919 return cursor;
920 }
921
922 public int previousIndex() {
923 return cursor - 1;
924 }
925
926 @SuppressWarnings("unchecked")
927 public E previous() {
928 checkForComodification();
929 int i = cursor - 1;
930 if (i < 0)
931 throw new NoSuchElementException();
932 Object[] elementData = ArrayList.this.elementData;
933 if (i >= elementData.length)
934 throw new ConcurrentModificationException();
935 cursor = i;
936 return (E) elementData[lastRet = i];
937 }
938
939 public void set(E e) {
940 if (lastRet < 0)
941 throw new IllegalStateException();
942 checkForComodification();
943
944 try {
945 ArrayList.this.set(lastRet, e);
946 } catch (IndexOutOfBoundsException ex) {
947 throw new ConcurrentModificationException();
948 }
949 }
950
951 public void add(E e) {
952 checkForComodification();
953
954 try {
955 int i = cursor;
956 ArrayList.this.add(i, e);
957 cursor = i + 1;
958 lastRet = -1;
959 expectedModCount = modCount;
960 } catch (IndexOutOfBoundsException ex) {
961 throw new ConcurrentModificationException();
962 }
963 }
964 }
965
966 /**
967 * Returns a view of the portion of this list between the specified
968 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If
969 * {@code fromIndex} and {@code toIndex} are equal, the returned list is
970 * empty.) The returned list is backed by this list, so non-structural
971 * changes in the returned list are reflected in this list, and vice-versa.
972 * The returned list supports all of the optional list operations.
973 *
974 * <p>This method eliminates the need for explicit range operations (of
975 * the sort that commonly exist for arrays). Any operation that expects
976 * a list can be used as a range operation by passing a subList view
977 * instead of a whole list. For example, the following idiom
978 * removes a range of elements from a list:
979 * <pre>
980 * list.subList(from, to).clear();
981 * </pre>
982 * Similar idioms may be constructed for {@link #indexOf(Object)} and
983 * {@link #lastIndexOf(Object)}, and all of the algorithms in the
984 * {@link Collections} class can be applied to a subList.
985 *
986 * <p>The semantics of the list returned by this method become undefined if
987 * the backing list (i.e., this list) is <i>structurally modified</i> in
988 * any way other than via the returned list. (Structural modifications are
989 * those that change the size of this list, or otherwise perturb it in such
990 * a fashion that iterations in progress may yield incorrect results.)
991 *
992 * @throws IndexOutOfBoundsException {@inheritDoc}
993 * @throws IllegalArgumentException {@inheritDoc}
994 */
995 public List<E> subList(int fromIndex, int toIndex) {
996 subListRangeCheck(fromIndex, toIndex, size);
997 return new SubList(this, 0, fromIndex, toIndex);
998 }
999
1000 static void subListRangeCheck(int fromIndex, int toIndex, int size) {
1001 if (fromIndex < 0)
1002 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
1003 if (toIndex > size)
1004 throw new IndexOutOfBoundsException("toIndex = " + toIndex);
1005 if (fromIndex > toIndex)
1006 throw new IllegalArgumentException("fromIndex(" + fromIndex +
1007 ") > toIndex(" + toIndex + ")");
1008 }
1009
1010 private class SubList extends AbstractList<E> implements RandomAccess {
1011 private final AbstractList<E> parent;
1012 private final int parentOffset;
1013 private final int offset;
1014 int size;
1015
1016 SubList(AbstractList<E> parent,
1017 int offset, int fromIndex, int toIndex) {
1018 this.parent = parent;
1019 this.parentOffset = fromIndex;
1020 this.offset = offset + fromIndex;
1021 this.size = toIndex - fromIndex;
1022 this.modCount = ArrayList.this.modCount;
1023 }
1024
1025 public E set(int index, E e) {
1026 rangeCheck(index);
1027 checkForComodification();
1028 E oldValue = ArrayList.this.elementData(offset + index);
1029 ArrayList.this.elementData[offset + index] = e;
1030 return oldValue;
1031 }
1032
1033 public E get(int index) {
1034 rangeCheck(index);
1035 checkForComodification();
1036 return ArrayList.this.elementData(offset + index);
1037 }
1038
1039 public int size() {
1040 checkForComodification();
1041 return this.size;
1042 }
1043
1044 public void add(int index, E e) {
1045 rangeCheckForAdd(index);
1046 checkForComodification();
1047 parent.add(parentOffset + index, e);
1048 this.modCount = parent.modCount;
1049 this.size++;
1050 }
1051
1052 public E remove(int index) {
1053 rangeCheck(index);
1054 checkForComodification();
1055 E result = parent.remove(parentOffset + index);
1056 this.modCount = parent.modCount;
1057 this.size--;
1058 return result;
1059 }
1060
1061 protected void removeRange(int fromIndex, int toIndex) {
1062 checkForComodification();
1063 parent.removeRange(parentOffset + fromIndex,
1064 parentOffset + toIndex);
1065 this.modCount = parent.modCount;
1066 this.size -= toIndex - fromIndex;
1067 }
1068
1069 public boolean addAll(Collection<? extends E> c) {
1070 return addAll(this.size, c);
1071 }
1072
1073 public boolean addAll(int index, Collection<? extends E> c) {
1074 rangeCheckForAdd(index);
1075 int cSize = c.size();
1076 if (cSize==0)
1077 return false;
1078
1079 checkForComodification();
1080 parent.addAll(parentOffset + index, c);
1081 this.modCount = parent.modCount;
1082 this.size += cSize;
1083 return true;
1084 }
1085
1086 public Iterator<E> iterator() {
1087 return listIterator();
1088 }
1089
1090 public ListIterator<E> listIterator(final int index) {
1091 checkForComodification();
1092 rangeCheckForAdd(index);
1093 final int offset = this.offset;
1094
1095 return new ListIterator<E>() {
1096 int cursor = index;
1097 int lastRet = -1;
1098 int expectedModCount = ArrayList.this.modCount;
1099
1100 public boolean hasNext() {
1101 return cursor != SubList.this.size;
1102 }
1103
1104 @SuppressWarnings("unchecked")
1105 public E next() {
1106 checkForComodification();
1107 int i = cursor;
1108 if (i >= SubList.this.size)
1109 throw new NoSuchElementException();
1110 Object[] elementData = ArrayList.this.elementData;
1111 if (offset + i >= elementData.length)
1112 throw new ConcurrentModificationException();
1113 cursor = i + 1;
1114 return (E) elementData[offset + (lastRet = i)];
1115 }
1116
1117 public boolean hasPrevious() {
1118 return cursor != 0;
1119 }
1120
1121 @SuppressWarnings("unchecked")
1122 public E previous() {
1123 checkForComodification();
1124 int i = cursor - 1;
1125 if (i < 0)
1126 throw new NoSuchElementException();
1127 Object[] elementData = ArrayList.this.elementData;
1128 if (offset + i >= elementData.length)
1129 throw new ConcurrentModificationException();
1130 cursor = i;
1131 return (E) elementData[offset + (lastRet = i)];
1132 }
1133
1134 @SuppressWarnings("unchecked")
1135 public void forEachRemaining(Consumer<? super E> consumer) {
1136 Objects.requireNonNull(consumer);
1137 final int size = SubList.this.size;
1138 int i = cursor;
1139 if (i >= size) {
1140 return;
1141 }
1142 final Object[] elementData = ArrayList.this.elementData;
1143 if (offset + i >= elementData.length) {
1144 throw new ConcurrentModificationException();
1145 }
1146 while (i != size && modCount == expectedModCount) {
1147 consumer.accept((E) elementData[offset + (i++)]);
1148 }
1149 // update once at end of iteration to reduce heap write traffic
1150 lastRet = cursor = i;
1151 checkForComodification();
1152 }
1153
1154 public int nextIndex() {
1155 return cursor;
1156 }
1157
1158 public int previousIndex() {
1159 return cursor - 1;
1160 }
1161
1162 public void remove() {
1163 if (lastRet < 0)
1164 throw new IllegalStateException();
1165 checkForComodification();
1166
1167 try {
1168 SubList.this.remove(lastRet);
1169 cursor = lastRet;
1170 lastRet = -1;
1171 expectedModCount = ArrayList.this.modCount;
1172 } catch (IndexOutOfBoundsException ex) {
1173 throw new ConcurrentModificationException();
1174 }
1175 }
1176
1177 public void set(E e) {
1178 if (lastRet < 0)
1179 throw new IllegalStateException();
1180 checkForComodification();
1181
1182 try {
1183 ArrayList.this.set(offset + lastRet, e);
1184 } catch (IndexOutOfBoundsException ex) {
1185 throw new ConcurrentModificationException();
1186 }
1187 }
1188
1189 public void add(E e) {
1190 checkForComodification();
1191
1192 try {
1193 int i = cursor;
1194 SubList.this.add(i, e);
1195 cursor = i + 1;
1196 lastRet = -1;
1197 expectedModCount = ArrayList.this.modCount;
1198 } catch (IndexOutOfBoundsException ex) {
1199 throw new ConcurrentModificationException();
1200 }
1201 }
1202
1203 final void checkForComodification() {
1204 if (expectedModCount != ArrayList.this.modCount)
1205 throw new ConcurrentModificationException();
1206 }
1207 };
1208 }
1209
1210 public List<E> subList(int fromIndex, int toIndex) {
1211 subListRangeCheck(fromIndex, toIndex, size);
1212 return new SubList(this, offset, fromIndex, toIndex);
1213 }
1214
1215 private void rangeCheck(int index) {
1216 if (index < 0 || index >= this.size)
1217 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1218 }
1219
1220 private void rangeCheckForAdd(int index) {
1221 if (index < 0 || index > this.size)
1222 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1223 }
1224
1225 private String outOfBoundsMsg(int index) {
1226 return "Index: "+index+", Size: "+this.size;
1227 }
1228
1229 private void checkForComodification() {
1230 if (ArrayList.this.modCount != this.modCount)
1231 throw new ConcurrentModificationException();
1232 }
1233
1234 public Spliterator<E> spliterator() {
1235 checkForComodification();
1236 return new ArrayListSpliterator<E>(ArrayList.this, offset,
1237 offset + this.size, this.modCount);
1238 }
1239 }
1240
1241 @Override
1242 public void forEach(Consumer<? super E> action) {
1243 Objects.requireNonNull(action);
1244 final int expectedModCount = modCount;
1245 @SuppressWarnings("unchecked")
1246 final E[] elementData = (E[]) this.elementData;
1247 final int size = this.size;
1248 for (int i=0; modCount == expectedModCount && i < size; i++) {
1249 action.accept(elementData[i]);
1250 }
1251 if (modCount != expectedModCount) {
1252 throw new ConcurrentModificationException();
1253 }
1254 }
1255
1256 /**
1257 * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
1258 * and <em>fail-fast</em> {@link Spliterator} over the elements in this
1259 * list.
1260 *
1261 * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
1262 * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.
1263 * Overriding implementations should document the reporting of additional
1264 * characteristic values.
1265 *
1266 * @return a {@code Spliterator} over the elements in this list
1267 * @since 1.8
1268 */
1269 @Override
1270 public Spliterator<E> spliterator() {
1271 return new ArrayListSpliterator<>(this, 0, -1, 0);
1272 }
1273
1274 /** Index-based split-by-two, lazily initialized Spliterator */
1275 static final class ArrayListSpliterator<E> implements Spliterator<E> {
1276
1277 /*
1278 * If ArrayLists were immutable, or structurally immutable (no
1279 * adds, removes, etc), we could implement their spliterators
1280 * with Arrays.spliterator. Instead we detect as much
1281 * interference during traversal as practical without
1282 * sacrificing much performance. We rely primarily on
1283 * modCounts. These are not guaranteed to detect concurrency
1284 * violations, and are sometimes overly conservative about
1285 * within-thread interference, but detect enough problems to
1286 * be worthwhile in practice. To carry this out, we (1) lazily
1287 * initialize fence and expectedModCount until the latest
1288 * point that we need to commit to the state we are checking
1289 * against; thus improving precision. (This doesn't apply to
1290 * SubLists, that create spliterators with current non-lazy
1291 * values). (2) We perform only a single
1292 * ConcurrentModificationException check at the end of forEach
1293 * (the most performance-sensitive method). When using forEach
1294 * (as opposed to iterators), we can normally only detect
1295 * interference after actions, not before. Further
1296 * CME-triggering checks apply to all other possible
1297 * violations of assumptions for example null or too-small
1298 * elementData array given its size(), that could only have
1299 * occurred due to interference. This allows the inner loop
1300 * of forEach to run without any further checks, and
1301 * simplifies lambda-resolution. While this does entail a
1302 * number of checks, note that in the common case of
1303 * list.stream().forEach(a), no checks or other computation
1304 * occur anywhere other than inside forEach itself. The other
1305 * less-often-used methods cannot take advantage of most of
1306 * these streamlinings.
1307 */
1308
1309 private final ArrayList<E> list;
1310 private int index; // current index, modified on advance/split
1311 private int fence; // -1 until used; then one past last index
1312 private int expectedModCount; // initialized when fence set
1313
1314 /** Create new spliterator covering the given range */
1315 ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
1316 int expectedModCount) {
1317 this.list = list; // OK if null unless traversed
1318 this.index = origin;
1319 this.fence = fence;
1320 this.expectedModCount = expectedModCount;
1321 }
1322
1323 private int getFence() { // initialize fence to size on first use
1324 int hi; // (a specialized variant appears in method forEach)
1325 ArrayList<E> lst;
1326 if ((hi = fence) < 0) {
1327 if ((lst = list) == null)
1328 hi = fence = 0;
1329 else {
1330 expectedModCount = lst.modCount;
1331 hi = fence = lst.size;
1332 }
1333 }
1334 return hi;
1335 }
1336
1337 public ArrayListSpliterator<E> trySplit() {
1338 int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
1339 return (lo >= mid) ? null : // divide range in half unless too small
1340 new ArrayListSpliterator<E>(list, lo, index = mid,
1341 expectedModCount);
1342 }
1343
1344 public boolean tryAdvance(Consumer<? super E> action) {
1345 if (action == null)
1346 throw new NullPointerException();
1347 int hi = getFence(), i = index;
1348 if (i < hi) {
1349 index = i + 1;
1350 @SuppressWarnings("unchecked") E e = (E)list.elementData[i];
1351 action.accept(e);
1352 if (list.modCount != expectedModCount)
1353 throw new ConcurrentModificationException();
1354 return true;
1355 }
1356 return false;
1357 }
1358
1359 public void forEachRemaining(Consumer<? super E> action) {
1360 int i, hi, mc; // hoist accesses and checks from loop
1361 ArrayList<E> lst; Object[] a;
1362 if (action == null)
1363 throw new NullPointerException();
1364 if ((lst = list) != null && (a = lst.elementData) != null) {
1365 if ((hi = fence) < 0) {
1366 mc = lst.modCount;
1367 hi = lst.size;
1368 }
1369 else
1370 mc = expectedModCount;
1371 if ((i = index) >= 0 && (index = hi) <= a.length) {
1372 for (; i < hi; ++i) {
1373 @SuppressWarnings("unchecked") E e = (E) a[i];
1374 action.accept(e);
1375 }
1376 if (lst.modCount == mc)
1377 return;
1378 }
1379 }
1380 throw new ConcurrentModificationException();
1381 }
1382
1383 public long estimateSize() {
1384 return (long) (getFence() - index);
1385 }
1386
1387 public int characteristics() {
1388 return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
1389 }
1390 }
1391
1392 @Override
1393 public boolean removeIf(Predicate<? super E> filter) {
1394 Objects.requireNonNull(filter);
1395 // figure out which elements are to be removed
1396 // any exception thrown from the filter predicate at this stage
1397 // will leave the collection unmodified
1398 int removeCount = 0;
1399 final BitSet removeSet = new BitSet(size);
1400 final int expectedModCount = modCount;
1401 final int size = this.size;
1402 for (int i=0; modCount == expectedModCount && i < size; i++) {
1403 @SuppressWarnings("unchecked")
1404 final E element = (E) elementData[i];
1405 if (filter.test(element)) {
1406 removeSet.set(i);
1407 removeCount++;
1408 }
1409 }
1410 if (modCount != expectedModCount) {
1411 throw new ConcurrentModificationException();
1412 }
1413
1414 // shift surviving elements left over the spaces left by removed elements
1415 final boolean anyToRemove = removeCount > 0;
1416 if (anyToRemove) {
1417 final int newSize = size - removeCount;
1418 for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
1419 i = removeSet.nextClearBit(i);
1420 elementData[j] = elementData[i];
1421 }
1422 for (int k=newSize; k < size; k++) {
1423 elementData[k] = null; // Let gc do its work
1424 }
1425 this.size = newSize;
1426 if (modCount != expectedModCount) {
1427 throw new ConcurrentModificationException();
1428 }
1429 modCount++;
1430 }
1431
1432 return anyToRemove;
1433 }
1434
1435 @Override
1436 @SuppressWarnings("unchecked")
1437 public void replaceAll(UnaryOperator<E> operator) {
1438 Objects.requireNonNull(operator);
1439 final int expectedModCount = modCount;
1440 final int size = this.size;
1441 for (int i=0; modCount == expectedModCount && i < size; i++) {
1442 elementData[i] = operator.apply((E) elementData[i]);
1443 }
1444 if (modCount != expectedModCount) {
1445 throw new ConcurrentModificationException();
1446 }
1447 modCount++;
1448 }
1449
1450 @Override
1451 @SuppressWarnings("unchecked")
1452 public void sort(Comparator<? super E> c) {
1453 final int expectedModCount = modCount;
1454 Arrays.sort((E[]) elementData, 0, size, c);
1455 if (modCount != expectedModCount) {
1456 throw new ConcurrentModificationException();
1457 }
1458 modCount++;
1459 }
1460}