1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/util/ArrayList.java Tue Feb 26 16:54:16 2013 +0100
1.3 @@ -0,0 +1,1088 @@
1.4 +/*
1.5 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.util;
1.30 +
1.31 +
1.32 +/**
1.33 + * Resizable-array implementation of the <tt>List</tt> interface. Implements
1.34 + * all optional list operations, and permits all elements, including
1.35 + * <tt>null</tt>. In addition to implementing the <tt>List</tt> interface,
1.36 + * this class provides methods to manipulate the size of the array that is
1.37 + * used internally to store the list. (This class is roughly equivalent to
1.38 + * <tt>Vector</tt>, except that it is unsynchronized.)
1.39 + *
1.40 + * <p>The <tt>size</tt>, <tt>isEmpty</tt>, <tt>get</tt>, <tt>set</tt>,
1.41 + * <tt>iterator</tt>, and <tt>listIterator</tt> operations run in constant
1.42 + * time. The <tt>add</tt> operation runs in <i>amortized constant time</i>,
1.43 + * that is, adding n elements requires O(n) time. All of the other operations
1.44 + * run in linear time (roughly speaking). The constant factor is low compared
1.45 + * to that for the <tt>LinkedList</tt> implementation.
1.46 + *
1.47 + * <p>Each <tt>ArrayList</tt> instance has a <i>capacity</i>. The capacity is
1.48 + * the size of the array used to store the elements in the list. It is always
1.49 + * at least as large as the list size. As elements are added to an ArrayList,
1.50 + * its capacity grows automatically. The details of the growth policy are not
1.51 + * specified beyond the fact that adding an element has constant amortized
1.52 + * time cost.
1.53 + *
1.54 + * <p>An application can increase the capacity of an <tt>ArrayList</tt> instance
1.55 + * before adding a large number of elements using the <tt>ensureCapacity</tt>
1.56 + * operation. This may reduce the amount of incremental reallocation.
1.57 + *
1.58 + * <p><strong>Note that this implementation is not synchronized.</strong>
1.59 + * If multiple threads access an <tt>ArrayList</tt> instance concurrently,
1.60 + * and at least one of the threads modifies the list structurally, it
1.61 + * <i>must</i> be synchronized externally. (A structural modification is
1.62 + * any operation that adds or deletes one or more elements, or explicitly
1.63 + * resizes the backing array; merely setting the value of an element is not
1.64 + * a structural modification.) This is typically accomplished by
1.65 + * synchronizing on some object that naturally encapsulates the list.
1.66 + *
1.67 + * If no such object exists, the list should be "wrapped" using the
1.68 + * {@link Collections#synchronizedList Collections.synchronizedList}
1.69 + * method. This is best done at creation time, to prevent accidental
1.70 + * unsynchronized access to the list:<pre>
1.71 + * List list = Collections.synchronizedList(new ArrayList(...));</pre>
1.72 + *
1.73 + * <p><a name="fail-fast"/>
1.74 + * The iterators returned by this class's {@link #iterator() iterator} and
1.75 + * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
1.76 + * if the list is structurally modified at any time after the iterator is
1.77 + * created, in any way except through the iterator's own
1.78 + * {@link ListIterator#remove() remove} or
1.79 + * {@link ListIterator#add(Object) add} methods, the iterator will throw a
1.80 + * {@link ConcurrentModificationException}. Thus, in the face of
1.81 + * concurrent modification, the iterator fails quickly and cleanly, rather
1.82 + * than risking arbitrary, non-deterministic behavior at an undetermined
1.83 + * time in the future.
1.84 + *
1.85 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
1.86 + * as it is, generally speaking, impossible to make any hard guarantees in the
1.87 + * presence of unsynchronized concurrent modification. Fail-fast iterators
1.88 + * throw {@code ConcurrentModificationException} on a best-effort basis.
1.89 + * Therefore, it would be wrong to write a program that depended on this
1.90 + * exception for its correctness: <i>the fail-fast behavior of iterators
1.91 + * should be used only to detect bugs.</i>
1.92 + *
1.93 + * <p>This class is a member of the
1.94 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
1.95 + * Java Collections Framework</a>.
1.96 + *
1.97 + * @author Josh Bloch
1.98 + * @author Neal Gafter
1.99 + * @see Collection
1.100 + * @see List
1.101 + * @see LinkedList
1.102 + * @see Vector
1.103 + * @since 1.2
1.104 + */
1.105 +
1.106 +public class ArrayList<E> extends AbstractList<E>
1.107 + implements List<E>, RandomAccess, Cloneable, java.io.Serializable
1.108 +{
1.109 + private static final long serialVersionUID = 8683452581122892189L;
1.110 +
1.111 + /**
1.112 + * The array buffer into which the elements of the ArrayList are stored.
1.113 + * The capacity of the ArrayList is the length of this array buffer.
1.114 + */
1.115 + private transient Object[] elementData;
1.116 +
1.117 + /**
1.118 + * The size of the ArrayList (the number of elements it contains).
1.119 + *
1.120 + * @serial
1.121 + */
1.122 + private int size;
1.123 +
1.124 + /**
1.125 + * Constructs an empty list with the specified initial capacity.
1.126 + *
1.127 + * @param initialCapacity the initial capacity of the list
1.128 + * @throws IllegalArgumentException if the specified initial capacity
1.129 + * is negative
1.130 + */
1.131 + public ArrayList(int initialCapacity) {
1.132 + super();
1.133 + if (initialCapacity < 0)
1.134 + throw new IllegalArgumentException("Illegal Capacity: "+
1.135 + initialCapacity);
1.136 + this.elementData = new Object[initialCapacity];
1.137 + }
1.138 +
1.139 + /**
1.140 + * Constructs an empty list with an initial capacity of ten.
1.141 + */
1.142 + public ArrayList() {
1.143 + this(10);
1.144 + }
1.145 +
1.146 + /**
1.147 + * Constructs a list containing the elements of the specified
1.148 + * collection, in the order they are returned by the collection's
1.149 + * iterator.
1.150 + *
1.151 + * @param c the collection whose elements are to be placed into this list
1.152 + * @throws NullPointerException if the specified collection is null
1.153 + */
1.154 + public ArrayList(Collection<? extends E> c) {
1.155 + elementData = c.toArray();
1.156 + size = elementData.length;
1.157 + // c.toArray might (incorrectly) not return Object[] (see 6260652)
1.158 + if (elementData.getClass() != Object[].class)
1.159 + elementData = Arrays.copyOf(elementData, size, Object[].class);
1.160 + }
1.161 +
1.162 + /**
1.163 + * Trims the capacity of this <tt>ArrayList</tt> instance to be the
1.164 + * list's current size. An application can use this operation to minimize
1.165 + * the storage of an <tt>ArrayList</tt> instance.
1.166 + */
1.167 + public void trimToSize() {
1.168 + modCount++;
1.169 + int oldCapacity = elementData.length;
1.170 + if (size < oldCapacity) {
1.171 + elementData = Arrays.copyOf(elementData, size);
1.172 + }
1.173 + }
1.174 +
1.175 + /**
1.176 + * Increases the capacity of this <tt>ArrayList</tt> instance, if
1.177 + * necessary, to ensure that it can hold at least the number of elements
1.178 + * specified by the minimum capacity argument.
1.179 + *
1.180 + * @param minCapacity the desired minimum capacity
1.181 + */
1.182 + public void ensureCapacity(int minCapacity) {
1.183 + if (minCapacity > 0)
1.184 + ensureCapacityInternal(minCapacity);
1.185 + }
1.186 +
1.187 + private void ensureCapacityInternal(int minCapacity) {
1.188 + modCount++;
1.189 + // overflow-conscious code
1.190 + if (minCapacity - elementData.length > 0)
1.191 + grow(minCapacity);
1.192 + }
1.193 +
1.194 + /**
1.195 + * The maximum size of array to allocate.
1.196 + * Some VMs reserve some header words in an array.
1.197 + * Attempts to allocate larger arrays may result in
1.198 + * OutOfMemoryError: Requested array size exceeds VM limit
1.199 + */
1.200 + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
1.201 +
1.202 + /**
1.203 + * Increases the capacity to ensure that it can hold at least the
1.204 + * number of elements specified by the minimum capacity argument.
1.205 + *
1.206 + * @param minCapacity the desired minimum capacity
1.207 + */
1.208 + private void grow(int minCapacity) {
1.209 + // overflow-conscious code
1.210 + int oldCapacity = elementData.length;
1.211 + int newCapacity = oldCapacity + (oldCapacity >> 1);
1.212 + if (newCapacity - minCapacity < 0)
1.213 + newCapacity = minCapacity;
1.214 + if (newCapacity - MAX_ARRAY_SIZE > 0)
1.215 + newCapacity = hugeCapacity(minCapacity);
1.216 + // minCapacity is usually close to size, so this is a win:
1.217 + elementData = Arrays.copyOf(elementData, newCapacity);
1.218 + }
1.219 +
1.220 + private static int hugeCapacity(int minCapacity) {
1.221 + if (minCapacity < 0) // overflow
1.222 + throw new OutOfMemoryError();
1.223 + return (minCapacity > MAX_ARRAY_SIZE) ?
1.224 + Integer.MAX_VALUE :
1.225 + MAX_ARRAY_SIZE;
1.226 + }
1.227 +
1.228 + /**
1.229 + * Returns the number of elements in this list.
1.230 + *
1.231 + * @return the number of elements in this list
1.232 + */
1.233 + public int size() {
1.234 + return size;
1.235 + }
1.236 +
1.237 + /**
1.238 + * Returns <tt>true</tt> if this list contains no elements.
1.239 + *
1.240 + * @return <tt>true</tt> if this list contains no elements
1.241 + */
1.242 + public boolean isEmpty() {
1.243 + return size == 0;
1.244 + }
1.245 +
1.246 + /**
1.247 + * Returns <tt>true</tt> if this list contains the specified element.
1.248 + * More formally, returns <tt>true</tt> if and only if this list contains
1.249 + * at least one element <tt>e</tt> such that
1.250 + * <tt>(o==null ? e==null : o.equals(e))</tt>.
1.251 + *
1.252 + * @param o element whose presence in this list is to be tested
1.253 + * @return <tt>true</tt> if this list contains the specified element
1.254 + */
1.255 + public boolean contains(Object o) {
1.256 + return indexOf(o) >= 0;
1.257 + }
1.258 +
1.259 + /**
1.260 + * Returns the index of the first occurrence of the specified element
1.261 + * in this list, or -1 if this list does not contain the element.
1.262 + * More formally, returns the lowest index <tt>i</tt> such that
1.263 + * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
1.264 + * or -1 if there is no such index.
1.265 + */
1.266 + public int indexOf(Object o) {
1.267 + if (o == null) {
1.268 + for (int i = 0; i < size; i++)
1.269 + if (elementData[i]==null)
1.270 + return i;
1.271 + } else {
1.272 + for (int i = 0; i < size; i++)
1.273 + if (o.equals(elementData[i]))
1.274 + return i;
1.275 + }
1.276 + return -1;
1.277 + }
1.278 +
1.279 + /**
1.280 + * Returns the index of the last occurrence of the specified element
1.281 + * in this list, or -1 if this list does not contain the element.
1.282 + * More formally, returns the highest index <tt>i</tt> such that
1.283 + * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
1.284 + * or -1 if there is no such index.
1.285 + */
1.286 + public int lastIndexOf(Object o) {
1.287 + if (o == null) {
1.288 + for (int i = size-1; i >= 0; i--)
1.289 + if (elementData[i]==null)
1.290 + return i;
1.291 + } else {
1.292 + for (int i = size-1; i >= 0; i--)
1.293 + if (o.equals(elementData[i]))
1.294 + return i;
1.295 + }
1.296 + return -1;
1.297 + }
1.298 +
1.299 + /**
1.300 + * Returns a shallow copy of this <tt>ArrayList</tt> instance. (The
1.301 + * elements themselves are not copied.)
1.302 + *
1.303 + * @return a clone of this <tt>ArrayList</tt> instance
1.304 + */
1.305 + public Object clone() {
1.306 + try {
1.307 + @SuppressWarnings("unchecked")
1.308 + ArrayList<E> v = (ArrayList<E>) super.clone();
1.309 + v.elementData = Arrays.copyOf(elementData, size);
1.310 + v.modCount = 0;
1.311 + return v;
1.312 + } catch (CloneNotSupportedException e) {
1.313 + // this shouldn't happen, since we are Cloneable
1.314 + throw new InternalError();
1.315 + }
1.316 + }
1.317 +
1.318 + /**
1.319 + * Returns an array containing all of the elements in this list
1.320 + * in proper sequence (from first to last element).
1.321 + *
1.322 + * <p>The returned array will be "safe" in that no references to it are
1.323 + * maintained by this list. (In other words, this method must allocate
1.324 + * a new array). The caller is thus free to modify the returned array.
1.325 + *
1.326 + * <p>This method acts as bridge between array-based and collection-based
1.327 + * APIs.
1.328 + *
1.329 + * @return an array containing all of the elements in this list in
1.330 + * proper sequence
1.331 + */
1.332 + public Object[] toArray() {
1.333 + return Arrays.copyOf(elementData, size);
1.334 + }
1.335 +
1.336 + /**
1.337 + * Returns an array containing all of the elements in this list in proper
1.338 + * sequence (from first to last element); the runtime type of the returned
1.339 + * array is that of the specified array. If the list fits in the
1.340 + * specified array, it is returned therein. Otherwise, a new array is
1.341 + * allocated with the runtime type of the specified array and the size of
1.342 + * this list.
1.343 + *
1.344 + * <p>If the list fits in the specified array with room to spare
1.345 + * (i.e., the array has more elements than the list), the element in
1.346 + * the array immediately following the end of the collection is set to
1.347 + * <tt>null</tt>. (This is useful in determining the length of the
1.348 + * list <i>only</i> if the caller knows that the list does not contain
1.349 + * any null elements.)
1.350 + *
1.351 + * @param a the array into which the elements of the list are to
1.352 + * be stored, if it is big enough; otherwise, a new array of the
1.353 + * same runtime type is allocated for this purpose.
1.354 + * @return an array containing the elements of the list
1.355 + * @throws ArrayStoreException if the runtime type of the specified array
1.356 + * is not a supertype of the runtime type of every element in
1.357 + * this list
1.358 + * @throws NullPointerException if the specified array is null
1.359 + */
1.360 + @SuppressWarnings("unchecked")
1.361 + public <T> T[] toArray(T[] a) {
1.362 + if (a.length < size)
1.363 + // Make a new array of a's runtime type, but my contents:
1.364 + return (T[]) Arrays.copyOf(elementData, size, a.getClass());
1.365 + System.arraycopy(elementData, 0, a, 0, size);
1.366 + if (a.length > size)
1.367 + a[size] = null;
1.368 + return a;
1.369 + }
1.370 +
1.371 + // Positional Access Operations
1.372 +
1.373 + @SuppressWarnings("unchecked")
1.374 + E elementData(int index) {
1.375 + return (E) elementData[index];
1.376 + }
1.377 +
1.378 + /**
1.379 + * Returns the element at the specified position in this list.
1.380 + *
1.381 + * @param index index of the element to return
1.382 + * @return the element at the specified position in this list
1.383 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.384 + */
1.385 + public E get(int index) {
1.386 + rangeCheck(index);
1.387 +
1.388 + return elementData(index);
1.389 + }
1.390 +
1.391 + /**
1.392 + * Replaces the element at the specified position in this list with
1.393 + * the specified element.
1.394 + *
1.395 + * @param index index of the element to replace
1.396 + * @param element element to be stored at the specified position
1.397 + * @return the element previously at the specified position
1.398 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.399 + */
1.400 + public E set(int index, E element) {
1.401 + rangeCheck(index);
1.402 +
1.403 + E oldValue = elementData(index);
1.404 + elementData[index] = element;
1.405 + return oldValue;
1.406 + }
1.407 +
1.408 + /**
1.409 + * Appends the specified element to the end of this list.
1.410 + *
1.411 + * @param e element to be appended to this list
1.412 + * @return <tt>true</tt> (as specified by {@link Collection#add})
1.413 + */
1.414 + public boolean add(E e) {
1.415 + ensureCapacityInternal(size + 1); // Increments modCount!!
1.416 + elementData[size++] = e;
1.417 + return true;
1.418 + }
1.419 +
1.420 + /**
1.421 + * Inserts the specified element at the specified position in this
1.422 + * list. Shifts the element currently at that position (if any) and
1.423 + * any subsequent elements to the right (adds one to their indices).
1.424 + *
1.425 + * @param index index at which the specified element is to be inserted
1.426 + * @param element element to be inserted
1.427 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.428 + */
1.429 + public void add(int index, E element) {
1.430 + rangeCheckForAdd(index);
1.431 +
1.432 + ensureCapacityInternal(size + 1); // Increments modCount!!
1.433 + System.arraycopy(elementData, index, elementData, index + 1,
1.434 + size - index);
1.435 + elementData[index] = element;
1.436 + size++;
1.437 + }
1.438 +
1.439 + /**
1.440 + * Removes the element at the specified position in this list.
1.441 + * Shifts any subsequent elements to the left (subtracts one from their
1.442 + * indices).
1.443 + *
1.444 + * @param index the index of the element to be removed
1.445 + * @return the element that was removed from the list
1.446 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.447 + */
1.448 + public E remove(int index) {
1.449 + rangeCheck(index);
1.450 +
1.451 + modCount++;
1.452 + E oldValue = elementData(index);
1.453 +
1.454 + int numMoved = size - index - 1;
1.455 + if (numMoved > 0)
1.456 + System.arraycopy(elementData, index+1, elementData, index,
1.457 + numMoved);
1.458 + elementData[--size] = null; // Let gc do its work
1.459 +
1.460 + return oldValue;
1.461 + }
1.462 +
1.463 + /**
1.464 + * Removes the first occurrence of the specified element from this list,
1.465 + * if it is present. If the list does not contain the element, it is
1.466 + * unchanged. More formally, removes the element with the lowest index
1.467 + * <tt>i</tt> such that
1.468 + * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
1.469 + * (if such an element exists). Returns <tt>true</tt> if this list
1.470 + * contained the specified element (or equivalently, if this list
1.471 + * changed as a result of the call).
1.472 + *
1.473 + * @param o element to be removed from this list, if present
1.474 + * @return <tt>true</tt> if this list contained the specified element
1.475 + */
1.476 + public boolean remove(Object o) {
1.477 + if (o == null) {
1.478 + for (int index = 0; index < size; index++)
1.479 + if (elementData[index] == null) {
1.480 + fastRemove(index);
1.481 + return true;
1.482 + }
1.483 + } else {
1.484 + for (int index = 0; index < size; index++)
1.485 + if (o.equals(elementData[index])) {
1.486 + fastRemove(index);
1.487 + return true;
1.488 + }
1.489 + }
1.490 + return false;
1.491 + }
1.492 +
1.493 + /*
1.494 + * Private remove method that skips bounds checking and does not
1.495 + * return the value removed.
1.496 + */
1.497 + private void fastRemove(int index) {
1.498 + modCount++;
1.499 + int numMoved = size - index - 1;
1.500 + if (numMoved > 0)
1.501 + System.arraycopy(elementData, index+1, elementData, index,
1.502 + numMoved);
1.503 + elementData[--size] = null; // Let gc do its work
1.504 + }
1.505 +
1.506 + /**
1.507 + * Removes all of the elements from this list. The list will
1.508 + * be empty after this call returns.
1.509 + */
1.510 + public void clear() {
1.511 + modCount++;
1.512 +
1.513 + // Let gc do its work
1.514 + for (int i = 0; i < size; i++)
1.515 + elementData[i] = null;
1.516 +
1.517 + size = 0;
1.518 + }
1.519 +
1.520 + /**
1.521 + * Appends all of the elements in the specified collection to the end of
1.522 + * this list, in the order that they are returned by the
1.523 + * specified collection's Iterator. The behavior of this operation is
1.524 + * undefined if the specified collection is modified while the operation
1.525 + * is in progress. (This implies that the behavior of this call is
1.526 + * undefined if the specified collection is this list, and this
1.527 + * list is nonempty.)
1.528 + *
1.529 + * @param c collection containing elements to be added to this list
1.530 + * @return <tt>true</tt> if this list changed as a result of the call
1.531 + * @throws NullPointerException if the specified collection is null
1.532 + */
1.533 + public boolean addAll(Collection<? extends E> c) {
1.534 + Object[] a = c.toArray();
1.535 + int numNew = a.length;
1.536 + ensureCapacityInternal(size + numNew); // Increments modCount
1.537 + System.arraycopy(a, 0, elementData, size, numNew);
1.538 + size += numNew;
1.539 + return numNew != 0;
1.540 + }
1.541 +
1.542 + /**
1.543 + * Inserts all of the elements in the specified collection into this
1.544 + * list, starting at the specified position. Shifts the element
1.545 + * currently at that position (if any) and any subsequent elements to
1.546 + * the right (increases their indices). The new elements will appear
1.547 + * in the list in the order that they are returned by the
1.548 + * specified collection's iterator.
1.549 + *
1.550 + * @param index index at which to insert the first element from the
1.551 + * specified collection
1.552 + * @param c collection containing elements to be added to this list
1.553 + * @return <tt>true</tt> if this list changed as a result of the call
1.554 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.555 + * @throws NullPointerException if the specified collection is null
1.556 + */
1.557 + public boolean addAll(int index, Collection<? extends E> c) {
1.558 + rangeCheckForAdd(index);
1.559 +
1.560 + Object[] a = c.toArray();
1.561 + int numNew = a.length;
1.562 + ensureCapacityInternal(size + numNew); // Increments modCount
1.563 +
1.564 + int numMoved = size - index;
1.565 + if (numMoved > 0)
1.566 + System.arraycopy(elementData, index, elementData, index + numNew,
1.567 + numMoved);
1.568 +
1.569 + System.arraycopy(a, 0, elementData, index, numNew);
1.570 + size += numNew;
1.571 + return numNew != 0;
1.572 + }
1.573 +
1.574 + /**
1.575 + * Removes from this list all of the elements whose index is between
1.576 + * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
1.577 + * Shifts any succeeding elements to the left (reduces their index).
1.578 + * This call shortens the list by {@code (toIndex - fromIndex)} elements.
1.579 + * (If {@code toIndex==fromIndex}, this operation has no effect.)
1.580 + *
1.581 + * @throws IndexOutOfBoundsException if {@code fromIndex} or
1.582 + * {@code toIndex} is out of range
1.583 + * ({@code fromIndex < 0 ||
1.584 + * fromIndex >= size() ||
1.585 + * toIndex > size() ||
1.586 + * toIndex < fromIndex})
1.587 + */
1.588 + protected void removeRange(int fromIndex, int toIndex) {
1.589 + modCount++;
1.590 + int numMoved = size - toIndex;
1.591 + System.arraycopy(elementData, toIndex, elementData, fromIndex,
1.592 + numMoved);
1.593 +
1.594 + // Let gc do its work
1.595 + int newSize = size - (toIndex-fromIndex);
1.596 + while (size != newSize)
1.597 + elementData[--size] = null;
1.598 + }
1.599 +
1.600 + /**
1.601 + * Checks if the given index is in range. If not, throws an appropriate
1.602 + * runtime exception. This method does *not* check if the index is
1.603 + * negative: It is always used immediately prior to an array access,
1.604 + * which throws an ArrayIndexOutOfBoundsException if index is negative.
1.605 + */
1.606 + private void rangeCheck(int index) {
1.607 + if (index >= size)
1.608 + throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1.609 + }
1.610 +
1.611 + /**
1.612 + * A version of rangeCheck used by add and addAll.
1.613 + */
1.614 + private void rangeCheckForAdd(int index) {
1.615 + if (index > size || index < 0)
1.616 + throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1.617 + }
1.618 +
1.619 + /**
1.620 + * Constructs an IndexOutOfBoundsException detail message.
1.621 + * Of the many possible refactorings of the error handling code,
1.622 + * this "outlining" performs best with both server and client VMs.
1.623 + */
1.624 + private String outOfBoundsMsg(int index) {
1.625 + return "Index: "+index+", Size: "+size;
1.626 + }
1.627 +
1.628 + /**
1.629 + * Removes from this list all of its elements that are contained in the
1.630 + * specified collection.
1.631 + *
1.632 + * @param c collection containing elements to be removed from this list
1.633 + * @return {@code true} if this list changed as a result of the call
1.634 + * @throws ClassCastException if the class of an element of this list
1.635 + * is incompatible with the specified collection
1.636 + * (<a href="Collection.html#optional-restrictions">optional</a>)
1.637 + * @throws NullPointerException if this list contains a null element and the
1.638 + * specified collection does not permit null elements
1.639 + * (<a href="Collection.html#optional-restrictions">optional</a>),
1.640 + * or if the specified collection is null
1.641 + * @see Collection#contains(Object)
1.642 + */
1.643 + public boolean removeAll(Collection<?> c) {
1.644 + return batchRemove(c, false);
1.645 + }
1.646 +
1.647 + /**
1.648 + * Retains only the elements in this list that are contained in the
1.649 + * specified collection. In other words, removes from this list all
1.650 + * of its elements that are not contained in the specified collection.
1.651 + *
1.652 + * @param c collection containing elements to be retained in this list
1.653 + * @return {@code true} if this list changed as a result of the call
1.654 + * @throws ClassCastException if the class of an element of this list
1.655 + * is incompatible with the specified collection
1.656 + * (<a href="Collection.html#optional-restrictions">optional</a>)
1.657 + * @throws NullPointerException if this list contains a null element and the
1.658 + * specified collection does not permit null elements
1.659 + * (<a href="Collection.html#optional-restrictions">optional</a>),
1.660 + * or if the specified collection is null
1.661 + * @see Collection#contains(Object)
1.662 + */
1.663 + public boolean retainAll(Collection<?> c) {
1.664 + return batchRemove(c, true);
1.665 + }
1.666 +
1.667 + private boolean batchRemove(Collection<?> c, boolean complement) {
1.668 + final Object[] elementData = this.elementData;
1.669 + int r = 0, w = 0;
1.670 + boolean modified = false;
1.671 + try {
1.672 + for (; r < size; r++)
1.673 + if (c.contains(elementData[r]) == complement)
1.674 + elementData[w++] = elementData[r];
1.675 + } finally {
1.676 + // Preserve behavioral compatibility with AbstractCollection,
1.677 + // even if c.contains() throws.
1.678 + if (r != size) {
1.679 + System.arraycopy(elementData, r,
1.680 + elementData, w,
1.681 + size - r);
1.682 + w += size - r;
1.683 + }
1.684 + if (w != size) {
1.685 + for (int i = w; i < size; i++)
1.686 + elementData[i] = null;
1.687 + modCount += size - w;
1.688 + size = w;
1.689 + modified = true;
1.690 + }
1.691 + }
1.692 + return modified;
1.693 + }
1.694 +
1.695 + /**
1.696 + * Returns a list iterator over the elements in this list (in proper
1.697 + * sequence), starting at the specified position in the list.
1.698 + * The specified index indicates the first element that would be
1.699 + * returned by an initial call to {@link ListIterator#next next}.
1.700 + * An initial call to {@link ListIterator#previous previous} would
1.701 + * return the element with the specified index minus one.
1.702 + *
1.703 + * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
1.704 + *
1.705 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.706 + */
1.707 + public ListIterator<E> listIterator(int index) {
1.708 + if (index < 0 || index > size)
1.709 + throw new IndexOutOfBoundsException("Index: "+index);
1.710 + return new ListItr(index);
1.711 + }
1.712 +
1.713 + /**
1.714 + * Returns a list iterator over the elements in this list (in proper
1.715 + * sequence).
1.716 + *
1.717 + * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
1.718 + *
1.719 + * @see #listIterator(int)
1.720 + */
1.721 + public ListIterator<E> listIterator() {
1.722 + return new ListItr(0);
1.723 + }
1.724 +
1.725 + /**
1.726 + * Returns an iterator over the elements in this list in proper sequence.
1.727 + *
1.728 + * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
1.729 + *
1.730 + * @return an iterator over the elements in this list in proper sequence
1.731 + */
1.732 + public Iterator<E> iterator() {
1.733 + return new Itr();
1.734 + }
1.735 +
1.736 + /**
1.737 + * An optimized version of AbstractList.Itr
1.738 + */
1.739 + private class Itr implements Iterator<E> {
1.740 + int cursor; // index of next element to return
1.741 + int lastRet = -1; // index of last element returned; -1 if no such
1.742 + int expectedModCount = modCount;
1.743 +
1.744 + public boolean hasNext() {
1.745 + return cursor != size;
1.746 + }
1.747 +
1.748 + @SuppressWarnings("unchecked")
1.749 + public E next() {
1.750 + checkForComodification();
1.751 + int i = cursor;
1.752 + if (i >= size)
1.753 + throw new NoSuchElementException();
1.754 + Object[] elementData = ArrayList.this.elementData;
1.755 + if (i >= elementData.length)
1.756 + throw new ConcurrentModificationException();
1.757 + cursor = i + 1;
1.758 + return (E) elementData[lastRet = i];
1.759 + }
1.760 +
1.761 + public void remove() {
1.762 + if (lastRet < 0)
1.763 + throw new IllegalStateException();
1.764 + checkForComodification();
1.765 +
1.766 + try {
1.767 + ArrayList.this.remove(lastRet);
1.768 + cursor = lastRet;
1.769 + lastRet = -1;
1.770 + expectedModCount = modCount;
1.771 + } catch (IndexOutOfBoundsException ex) {
1.772 + throw new ConcurrentModificationException();
1.773 + }
1.774 + }
1.775 +
1.776 + final void checkForComodification() {
1.777 + if (modCount != expectedModCount)
1.778 + throw new ConcurrentModificationException();
1.779 + }
1.780 + }
1.781 +
1.782 + /**
1.783 + * An optimized version of AbstractList.ListItr
1.784 + */
1.785 + private class ListItr extends Itr implements ListIterator<E> {
1.786 + ListItr(int index) {
1.787 + super();
1.788 + cursor = index;
1.789 + }
1.790 +
1.791 + public boolean hasPrevious() {
1.792 + return cursor != 0;
1.793 + }
1.794 +
1.795 + public int nextIndex() {
1.796 + return cursor;
1.797 + }
1.798 +
1.799 + public int previousIndex() {
1.800 + return cursor - 1;
1.801 + }
1.802 +
1.803 + @SuppressWarnings("unchecked")
1.804 + public E previous() {
1.805 + checkForComodification();
1.806 + int i = cursor - 1;
1.807 + if (i < 0)
1.808 + throw new NoSuchElementException();
1.809 + Object[] elementData = ArrayList.this.elementData;
1.810 + if (i >= elementData.length)
1.811 + throw new ConcurrentModificationException();
1.812 + cursor = i;
1.813 + return (E) elementData[lastRet = i];
1.814 + }
1.815 +
1.816 + public void set(E e) {
1.817 + if (lastRet < 0)
1.818 + throw new IllegalStateException();
1.819 + checkForComodification();
1.820 +
1.821 + try {
1.822 + ArrayList.this.set(lastRet, e);
1.823 + } catch (IndexOutOfBoundsException ex) {
1.824 + throw new ConcurrentModificationException();
1.825 + }
1.826 + }
1.827 +
1.828 + public void add(E e) {
1.829 + checkForComodification();
1.830 +
1.831 + try {
1.832 + int i = cursor;
1.833 + ArrayList.this.add(i, e);
1.834 + cursor = i + 1;
1.835 + lastRet = -1;
1.836 + expectedModCount = modCount;
1.837 + } catch (IndexOutOfBoundsException ex) {
1.838 + throw new ConcurrentModificationException();
1.839 + }
1.840 + }
1.841 + }
1.842 +
1.843 + /**
1.844 + * Returns a view of the portion of this list between the specified
1.845 + * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If
1.846 + * {@code fromIndex} and {@code toIndex} are equal, the returned list is
1.847 + * empty.) The returned list is backed by this list, so non-structural
1.848 + * changes in the returned list are reflected in this list, and vice-versa.
1.849 + * The returned list supports all of the optional list operations.
1.850 + *
1.851 + * <p>This method eliminates the need for explicit range operations (of
1.852 + * the sort that commonly exist for arrays). Any operation that expects
1.853 + * a list can be used as a range operation by passing a subList view
1.854 + * instead of a whole list. For example, the following idiom
1.855 + * removes a range of elements from a list:
1.856 + * <pre>
1.857 + * list.subList(from, to).clear();
1.858 + * </pre>
1.859 + * Similar idioms may be constructed for {@link #indexOf(Object)} and
1.860 + * {@link #lastIndexOf(Object)}, and all of the algorithms in the
1.861 + * {@link Collections} class can be applied to a subList.
1.862 + *
1.863 + * <p>The semantics of the list returned by this method become undefined if
1.864 + * the backing list (i.e., this list) is <i>structurally modified</i> in
1.865 + * any way other than via the returned list. (Structural modifications are
1.866 + * those that change the size of this list, or otherwise perturb it in such
1.867 + * a fashion that iterations in progress may yield incorrect results.)
1.868 + *
1.869 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.870 + * @throws IllegalArgumentException {@inheritDoc}
1.871 + */
1.872 + public List<E> subList(int fromIndex, int toIndex) {
1.873 + subListRangeCheck(fromIndex, toIndex, size);
1.874 + return new SubList(this, 0, fromIndex, toIndex);
1.875 + }
1.876 +
1.877 + static void subListRangeCheck(int fromIndex, int toIndex, int size) {
1.878 + if (fromIndex < 0)
1.879 + throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
1.880 + if (toIndex > size)
1.881 + throw new IndexOutOfBoundsException("toIndex = " + toIndex);
1.882 + if (fromIndex > toIndex)
1.883 + throw new IllegalArgumentException("fromIndex(" + fromIndex +
1.884 + ") > toIndex(" + toIndex + ")");
1.885 + }
1.886 +
1.887 + private class SubList extends AbstractList<E> implements RandomAccess {
1.888 + private final AbstractList<E> parent;
1.889 + private final int parentOffset;
1.890 + private final int offset;
1.891 + int size;
1.892 +
1.893 + SubList(AbstractList<E> parent,
1.894 + int offset, int fromIndex, int toIndex) {
1.895 + this.parent = parent;
1.896 + this.parentOffset = fromIndex;
1.897 + this.offset = offset + fromIndex;
1.898 + this.size = toIndex - fromIndex;
1.899 + this.modCount = ArrayList.this.modCount;
1.900 + }
1.901 +
1.902 + public E set(int index, E e) {
1.903 + rangeCheck(index);
1.904 + checkForComodification();
1.905 + E oldValue = ArrayList.this.elementData(offset + index);
1.906 + ArrayList.this.elementData[offset + index] = e;
1.907 + return oldValue;
1.908 + }
1.909 +
1.910 + public E get(int index) {
1.911 + rangeCheck(index);
1.912 + checkForComodification();
1.913 + return ArrayList.this.elementData(offset + index);
1.914 + }
1.915 +
1.916 + public int size() {
1.917 + checkForComodification();
1.918 + return this.size;
1.919 + }
1.920 +
1.921 + public void add(int index, E e) {
1.922 + rangeCheckForAdd(index);
1.923 + checkForComodification();
1.924 + parent.add(parentOffset + index, e);
1.925 + this.modCount = parent.modCount;
1.926 + this.size++;
1.927 + }
1.928 +
1.929 + public E remove(int index) {
1.930 + rangeCheck(index);
1.931 + checkForComodification();
1.932 + E result = parent.remove(parentOffset + index);
1.933 + this.modCount = parent.modCount;
1.934 + this.size--;
1.935 + return result;
1.936 + }
1.937 +
1.938 + protected void removeRange(int fromIndex, int toIndex) {
1.939 + checkForComodification();
1.940 + parent.removeRange(parentOffset + fromIndex,
1.941 + parentOffset + toIndex);
1.942 + this.modCount = parent.modCount;
1.943 + this.size -= toIndex - fromIndex;
1.944 + }
1.945 +
1.946 + public boolean addAll(Collection<? extends E> c) {
1.947 + return addAll(this.size, c);
1.948 + }
1.949 +
1.950 + public boolean addAll(int index, Collection<? extends E> c) {
1.951 + rangeCheckForAdd(index);
1.952 + int cSize = c.size();
1.953 + if (cSize==0)
1.954 + return false;
1.955 +
1.956 + checkForComodification();
1.957 + parent.addAll(parentOffset + index, c);
1.958 + this.modCount = parent.modCount;
1.959 + this.size += cSize;
1.960 + return true;
1.961 + }
1.962 +
1.963 + public Iterator<E> iterator() {
1.964 + return listIterator();
1.965 + }
1.966 +
1.967 + public ListIterator<E> listIterator(final int index) {
1.968 + checkForComodification();
1.969 + rangeCheckForAdd(index);
1.970 + final int offset = this.offset;
1.971 +
1.972 + return new ListIterator<E>() {
1.973 + int cursor = index;
1.974 + int lastRet = -1;
1.975 + int expectedModCount = ArrayList.this.modCount;
1.976 +
1.977 + public boolean hasNext() {
1.978 + return cursor != SubList.this.size;
1.979 + }
1.980 +
1.981 + @SuppressWarnings("unchecked")
1.982 + public E next() {
1.983 + checkForComodification();
1.984 + int i = cursor;
1.985 + if (i >= SubList.this.size)
1.986 + throw new NoSuchElementException();
1.987 + Object[] elementData = ArrayList.this.elementData;
1.988 + if (offset + i >= elementData.length)
1.989 + throw new ConcurrentModificationException();
1.990 + cursor = i + 1;
1.991 + return (E) elementData[offset + (lastRet = i)];
1.992 + }
1.993 +
1.994 + public boolean hasPrevious() {
1.995 + return cursor != 0;
1.996 + }
1.997 +
1.998 + @SuppressWarnings("unchecked")
1.999 + public E previous() {
1.1000 + checkForComodification();
1.1001 + int i = cursor - 1;
1.1002 + if (i < 0)
1.1003 + throw new NoSuchElementException();
1.1004 + Object[] elementData = ArrayList.this.elementData;
1.1005 + if (offset + i >= elementData.length)
1.1006 + throw new ConcurrentModificationException();
1.1007 + cursor = i;
1.1008 + return (E) elementData[offset + (lastRet = i)];
1.1009 + }
1.1010 +
1.1011 + public int nextIndex() {
1.1012 + return cursor;
1.1013 + }
1.1014 +
1.1015 + public int previousIndex() {
1.1016 + return cursor - 1;
1.1017 + }
1.1018 +
1.1019 + public void remove() {
1.1020 + if (lastRet < 0)
1.1021 + throw new IllegalStateException();
1.1022 + checkForComodification();
1.1023 +
1.1024 + try {
1.1025 + SubList.this.remove(lastRet);
1.1026 + cursor = lastRet;
1.1027 + lastRet = -1;
1.1028 + expectedModCount = ArrayList.this.modCount;
1.1029 + } catch (IndexOutOfBoundsException ex) {
1.1030 + throw new ConcurrentModificationException();
1.1031 + }
1.1032 + }
1.1033 +
1.1034 + public void set(E e) {
1.1035 + if (lastRet < 0)
1.1036 + throw new IllegalStateException();
1.1037 + checkForComodification();
1.1038 +
1.1039 + try {
1.1040 + ArrayList.this.set(offset + lastRet, e);
1.1041 + } catch (IndexOutOfBoundsException ex) {
1.1042 + throw new ConcurrentModificationException();
1.1043 + }
1.1044 + }
1.1045 +
1.1046 + public void add(E e) {
1.1047 + checkForComodification();
1.1048 +
1.1049 + try {
1.1050 + int i = cursor;
1.1051 + SubList.this.add(i, e);
1.1052 + cursor = i + 1;
1.1053 + lastRet = -1;
1.1054 + expectedModCount = ArrayList.this.modCount;
1.1055 + } catch (IndexOutOfBoundsException ex) {
1.1056 + throw new ConcurrentModificationException();
1.1057 + }
1.1058 + }
1.1059 +
1.1060 + final void checkForComodification() {
1.1061 + if (expectedModCount != ArrayList.this.modCount)
1.1062 + throw new ConcurrentModificationException();
1.1063 + }
1.1064 + };
1.1065 + }
1.1066 +
1.1067 + public List<E> subList(int fromIndex, int toIndex) {
1.1068 + subListRangeCheck(fromIndex, toIndex, size);
1.1069 + return new SubList(this, offset, fromIndex, toIndex);
1.1070 + }
1.1071 +
1.1072 + private void rangeCheck(int index) {
1.1073 + if (index < 0 || index >= this.size)
1.1074 + throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1.1075 + }
1.1076 +
1.1077 + private void rangeCheckForAdd(int index) {
1.1078 + if (index < 0 || index > this.size)
1.1079 + throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1.1080 + }
1.1081 +
1.1082 + private String outOfBoundsMsg(int index) {
1.1083 + return "Index: "+index+", Size: "+this.size;
1.1084 + }
1.1085 +
1.1086 + private void checkForComodification() {
1.1087 + if (ArrayList.this.modCount != this.modCount)
1.1088 + throw new ConcurrentModificationException();
1.1089 + }
1.1090 + }
1.1091 +}