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