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