diff -r 4252bfc396fc -r d382dacfd73f emul/compact/src/main/java/java/util/ArrayList.java --- a/emul/compact/src/main/java/java/util/ArrayList.java Tue Feb 26 14:55:55 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1088 +0,0 @@ -/* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util; - - -/** - * Resizable-array implementation of the List interface. Implements - * all optional list operations, and permits all elements, including - * null. In addition to implementing the List interface, - * this class provides methods to manipulate the size of the array that is - * used internally to store the list. (This class is roughly equivalent to - * Vector, except that it is unsynchronized.) - * - *

The size, isEmpty, get, set, - * iterator, and listIterator operations run in constant - * time. The add operation runs in amortized constant time, - * that is, adding n elements requires O(n) time. All of the other operations - * run in linear time (roughly speaking). The constant factor is low compared - * to that for the LinkedList implementation. - * - *

Each ArrayList instance has a capacity. The capacity is - * the size of the array used to store the elements in the list. It is always - * at least as large as the list size. As elements are added to an ArrayList, - * its capacity grows automatically. The details of the growth policy are not - * specified beyond the fact that adding an element has constant amortized - * time cost. - * - *

An application can increase the capacity of an ArrayList instance - * before adding a large number of elements using the ensureCapacity - * operation. This may reduce the amount of incremental reallocation. - * - *

Note that this implementation is not synchronized. - * If multiple threads access an ArrayList instance concurrently, - * and at least one of the threads modifies the list structurally, it - * must be synchronized externally. (A structural modification is - * any operation that adds or deletes one or more elements, or explicitly - * resizes the backing array; merely setting the value of an element is not - * a structural modification.) This is typically accomplished by - * synchronizing on some object that naturally encapsulates the list. - * - * If no such object exists, the list should be "wrapped" using the - * {@link Collections#synchronizedList Collections.synchronizedList} - * method. This is best done at creation time, to prevent accidental - * unsynchronized access to the list:

- *   List list = Collections.synchronizedList(new ArrayList(...));
- * - *

- * The iterators returned by this class's {@link #iterator() iterator} and - * {@link #listIterator(int) listIterator} methods are fail-fast: - * if the list is structurally modified at any time after the iterator is - * created, in any way except through the iterator's own - * {@link ListIterator#remove() remove} or - * {@link ListIterator#add(Object) add} methods, the iterator will throw a - * {@link ConcurrentModificationException}. Thus, in the face of - * concurrent modification, the iterator fails quickly and cleanly, rather - * than risking arbitrary, non-deterministic behavior at an undetermined - * time in the future. - * - *

Note that the fail-fast behavior of an iterator cannot be guaranteed - * as it is, generally speaking, impossible to make any hard guarantees in the - * presence of unsynchronized concurrent modification. Fail-fast iterators - * throw {@code ConcurrentModificationException} on a best-effort basis. - * Therefore, it would be wrong to write a program that depended on this - * exception for its correctness: the fail-fast behavior of iterators - * should be used only to detect bugs. - * - *

This class is a member of the - * - * Java Collections Framework. - * - * @author Josh Bloch - * @author Neal Gafter - * @see Collection - * @see List - * @see LinkedList - * @see Vector - * @since 1.2 - */ - -public class ArrayList extends AbstractList - implements List, RandomAccess, Cloneable, java.io.Serializable -{ - private static final long serialVersionUID = 8683452581122892189L; - - /** - * The array buffer into which the elements of the ArrayList are stored. - * The capacity of the ArrayList is the length of this array buffer. - */ - private transient Object[] elementData; - - /** - * The size of the ArrayList (the number of elements it contains). - * - * @serial - */ - private int size; - - /** - * Constructs an empty list with the specified initial capacity. - * - * @param initialCapacity the initial capacity of the list - * @throws IllegalArgumentException if the specified initial capacity - * is negative - */ - public ArrayList(int initialCapacity) { - super(); - if (initialCapacity < 0) - throw new IllegalArgumentException("Illegal Capacity: "+ - initialCapacity); - this.elementData = new Object[initialCapacity]; - } - - /** - * Constructs an empty list with an initial capacity of ten. - */ - public ArrayList() { - this(10); - } - - /** - * Constructs a list containing the elements of the specified - * collection, in the order they are returned by the collection's - * iterator. - * - * @param c the collection whose elements are to be placed into this list - * @throws NullPointerException if the specified collection is null - */ - public ArrayList(Collection c) { - elementData = c.toArray(); - size = elementData.length; - // c.toArray might (incorrectly) not return Object[] (see 6260652) - if (elementData.getClass() != Object[].class) - elementData = Arrays.copyOf(elementData, size, Object[].class); - } - - /** - * Trims the capacity of this ArrayList instance to be the - * list's current size. An application can use this operation to minimize - * the storage of an ArrayList instance. - */ - public void trimToSize() { - modCount++; - int oldCapacity = elementData.length; - if (size < oldCapacity) { - elementData = Arrays.copyOf(elementData, size); - } - } - - /** - * Increases the capacity of this ArrayList instance, if - * necessary, to ensure that it can hold at least the number of elements - * specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity - */ - public void ensureCapacity(int minCapacity) { - if (minCapacity > 0) - ensureCapacityInternal(minCapacity); - } - - private void ensureCapacityInternal(int minCapacity) { - modCount++; - // overflow-conscious code - if (minCapacity - elementData.length > 0) - grow(minCapacity); - } - - /** - * The maximum size of array to allocate. - * Some VMs reserve some header words in an array. - * Attempts to allocate larger arrays may result in - * OutOfMemoryError: Requested array size exceeds VM limit - */ - private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; - - /** - * Increases the capacity to ensure that it can hold at least the - * number of elements specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity - */ - private void grow(int minCapacity) { - // overflow-conscious code - int oldCapacity = elementData.length; - int newCapacity = oldCapacity + (oldCapacity >> 1); - if (newCapacity - minCapacity < 0) - newCapacity = minCapacity; - if (newCapacity - MAX_ARRAY_SIZE > 0) - newCapacity = hugeCapacity(minCapacity); - // minCapacity is usually close to size, so this is a win: - elementData = Arrays.copyOf(elementData, newCapacity); - } - - private static int hugeCapacity(int minCapacity) { - if (minCapacity < 0) // overflow - throw new OutOfMemoryError(); - return (minCapacity > MAX_ARRAY_SIZE) ? - Integer.MAX_VALUE : - MAX_ARRAY_SIZE; - } - - /** - * Returns the number of elements in this list. - * - * @return the number of elements in this list - */ - public int size() { - return size; - } - - /** - * Returns true if this list contains no elements. - * - * @return true if this list contains no elements - */ - public boolean isEmpty() { - return size == 0; - } - - /** - * Returns true if this list contains the specified element. - * More formally, returns true if and only if this list contains - * at least one element e such that - * (o==null ? e==null : o.equals(e)). - * - * @param o element whose presence in this list is to be tested - * @return true if this list contains the specified element - */ - public boolean contains(Object o) { - return indexOf(o) >= 0; - } - - /** - * Returns the index of the first occurrence of the specified element - * in this list, or -1 if this list does not contain the element. - * More formally, returns the lowest index i such that - * (o==null ? get(i)==null : o.equals(get(i))), - * or -1 if there is no such index. - */ - public int indexOf(Object o) { - if (o == null) { - for (int i = 0; i < size; i++) - if (elementData[i]==null) - return i; - } else { - for (int i = 0; i < size; i++) - if (o.equals(elementData[i])) - return i; - } - return -1; - } - - /** - * Returns the index of the last occurrence of the specified element - * in this list, or -1 if this list does not contain the element. - * More formally, returns the highest index i such that - * (o==null ? get(i)==null : o.equals(get(i))), - * or -1 if there is no such index. - */ - public int lastIndexOf(Object o) { - if (o == null) { - for (int i = size-1; i >= 0; i--) - if (elementData[i]==null) - return i; - } else { - for (int i = size-1; i >= 0; i--) - if (o.equals(elementData[i])) - return i; - } - return -1; - } - - /** - * Returns a shallow copy of this ArrayList instance. (The - * elements themselves are not copied.) - * - * @return a clone of this ArrayList instance - */ - public Object clone() { - try { - @SuppressWarnings("unchecked") - ArrayList v = (ArrayList) super.clone(); - v.elementData = Arrays.copyOf(elementData, size); - v.modCount = 0; - return v; - } catch (CloneNotSupportedException e) { - // this shouldn't happen, since we are Cloneable - throw new InternalError(); - } - } - - /** - * Returns an array containing all of the elements in this list - * in proper sequence (from first to last element). - * - *

The returned array will be "safe" in that no references to it are - * maintained by this list. (In other words, this method must allocate - * a new array). The caller is thus free to modify the returned array. - * - *

This method acts as bridge between array-based and collection-based - * APIs. - * - * @return an array containing all of the elements in this list in - * proper sequence - */ - public Object[] toArray() { - return Arrays.copyOf(elementData, size); - } - - /** - * Returns an array containing all of the elements in this list in proper - * sequence (from first to last element); the runtime type of the returned - * array is that of the specified array. If the list fits in the - * specified array, it is returned therein. Otherwise, a new array is - * allocated with the runtime type of the specified array and the size of - * this list. - * - *

If the list fits in the specified array with room to spare - * (i.e., the array has more elements than the list), the element in - * the array immediately following the end of the collection is set to - * null. (This is useful in determining the length of the - * list only if the caller knows that the list does not contain - * any null elements.) - * - * @param a the array into which the elements of the list are to - * be stored, if it is big enough; otherwise, a new array of the - * same runtime type is allocated for this purpose. - * @return an array containing the elements of the list - * @throws ArrayStoreException if the runtime type of the specified array - * is not a supertype of the runtime type of every element in - * this list - * @throws NullPointerException if the specified array is null - */ - @SuppressWarnings("unchecked") - public T[] toArray(T[] a) { - if (a.length < size) - // Make a new array of a's runtime type, but my contents: - return (T[]) Arrays.copyOf(elementData, size, a.getClass()); - System.arraycopy(elementData, 0, a, 0, size); - if (a.length > size) - a[size] = null; - return a; - } - - // Positional Access Operations - - @SuppressWarnings("unchecked") - E elementData(int index) { - return (E) elementData[index]; - } - - /** - * Returns the element at the specified position in this list. - * - * @param index index of the element to return - * @return the element at the specified position in this list - * @throws IndexOutOfBoundsException {@inheritDoc} - */ - public E get(int index) { - rangeCheck(index); - - return elementData(index); - } - - /** - * Replaces the element at the specified position in this list with - * the specified element. - * - * @param index index of the element to replace - * @param element element to be stored at the specified position - * @return the element previously at the specified position - * @throws IndexOutOfBoundsException {@inheritDoc} - */ - public E set(int index, E element) { - rangeCheck(index); - - E oldValue = elementData(index); - elementData[index] = element; - return oldValue; - } - - /** - * Appends the specified element to the end of this list. - * - * @param e element to be appended to this list - * @return true (as specified by {@link Collection#add}) - */ - public boolean add(E e) { - ensureCapacityInternal(size + 1); // Increments modCount!! - elementData[size++] = e; - return true; - } - - /** - * Inserts the specified element at the specified position in this - * list. Shifts the element currently at that position (if any) and - * any subsequent elements to the right (adds one to their indices). - * - * @param index index at which the specified element is to be inserted - * @param element element to be inserted - * @throws IndexOutOfBoundsException {@inheritDoc} - */ - public void add(int index, E element) { - rangeCheckForAdd(index); - - ensureCapacityInternal(size + 1); // Increments modCount!! - System.arraycopy(elementData, index, elementData, index + 1, - size - index); - elementData[index] = element; - size++; - } - - /** - * Removes the element at the specified position in this list. - * Shifts any subsequent elements to the left (subtracts one from their - * indices). - * - * @param index the index of the element to be removed - * @return the element that was removed from the list - * @throws IndexOutOfBoundsException {@inheritDoc} - */ - public E remove(int index) { - rangeCheck(index); - - modCount++; - E oldValue = elementData(index); - - int numMoved = size - index - 1; - if (numMoved > 0) - System.arraycopy(elementData, index+1, elementData, index, - numMoved); - elementData[--size] = null; // Let gc do its work - - return oldValue; - } - - /** - * Removes the first occurrence of the specified element from this list, - * if it is present. If the list does not contain the element, it is - * unchanged. More formally, removes the element with the lowest index - * i such that - * (o==null ? get(i)==null : o.equals(get(i))) - * (if such an element exists). Returns true if this list - * contained the specified element (or equivalently, if this list - * changed as a result of the call). - * - * @param o element to be removed from this list, if present - * @return true if this list contained the specified element - */ - public boolean remove(Object o) { - if (o == null) { - for (int index = 0; index < size; index++) - if (elementData[index] == null) { - fastRemove(index); - return true; - } - } else { - for (int index = 0; index < size; index++) - if (o.equals(elementData[index])) { - fastRemove(index); - return true; - } - } - return false; - } - - /* - * Private remove method that skips bounds checking and does not - * return the value removed. - */ - private void fastRemove(int index) { - modCount++; - int numMoved = size - index - 1; - if (numMoved > 0) - System.arraycopy(elementData, index+1, elementData, index, - numMoved); - elementData[--size] = null; // Let gc do its work - } - - /** - * Removes all of the elements from this list. The list will - * be empty after this call returns. - */ - public void clear() { - modCount++; - - // Let gc do its work - for (int i = 0; i < size; i++) - elementData[i] = null; - - size = 0; - } - - /** - * Appends all of the elements in the specified collection to the end of - * this list, in the order that they are returned by the - * specified collection's Iterator. The behavior of this operation is - * undefined if the specified collection is modified while the operation - * is in progress. (This implies that the behavior of this call is - * undefined if the specified collection is this list, and this - * list is nonempty.) - * - * @param c collection containing elements to be added to this list - * @return true if this list changed as a result of the call - * @throws NullPointerException if the specified collection is null - */ - public boolean addAll(Collection c) { - Object[] a = c.toArray(); - int numNew = a.length; - ensureCapacityInternal(size + numNew); // Increments modCount - System.arraycopy(a, 0, elementData, size, numNew); - size += numNew; - return numNew != 0; - } - - /** - * Inserts all of the elements in the specified collection into this - * list, starting at the specified position. Shifts the element - * currently at that position (if any) and any subsequent elements to - * the right (increases their indices). The new elements will appear - * in the list in the order that they are returned by the - * specified collection's iterator. - * - * @param index index at which to insert the first element from the - * specified collection - * @param c collection containing elements to be added to this list - * @return true if this list changed as a result of the call - * @throws IndexOutOfBoundsException {@inheritDoc} - * @throws NullPointerException if the specified collection is null - */ - public boolean addAll(int index, Collection c) { - rangeCheckForAdd(index); - - Object[] a = c.toArray(); - int numNew = a.length; - ensureCapacityInternal(size + numNew); // Increments modCount - - int numMoved = size - index; - if (numMoved > 0) - System.arraycopy(elementData, index, elementData, index + numNew, - numMoved); - - System.arraycopy(a, 0, elementData, index, numNew); - size += numNew; - return numNew != 0; - } - - /** - * Removes from this list all of the elements whose index is between - * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. - * Shifts any succeeding elements to the left (reduces their index). - * This call shortens the list by {@code (toIndex - fromIndex)} elements. - * (If {@code toIndex==fromIndex}, this operation has no effect.) - * - * @throws IndexOutOfBoundsException if {@code fromIndex} or - * {@code toIndex} is out of range - * ({@code fromIndex < 0 || - * fromIndex >= size() || - * toIndex > size() || - * toIndex < fromIndex}) - */ - protected void removeRange(int fromIndex, int toIndex) { - modCount++; - int numMoved = size - toIndex; - System.arraycopy(elementData, toIndex, elementData, fromIndex, - numMoved); - - // Let gc do its work - int newSize = size - (toIndex-fromIndex); - while (size != newSize) - elementData[--size] = null; - } - - /** - * Checks if the given index is in range. If not, throws an appropriate - * runtime exception. This method does *not* check if the index is - * negative: It is always used immediately prior to an array access, - * which throws an ArrayIndexOutOfBoundsException if index is negative. - */ - private void rangeCheck(int index) { - if (index >= size) - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - - /** - * A version of rangeCheck used by add and addAll. - */ - private void rangeCheckForAdd(int index) { - if (index > size || index < 0) - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - - /** - * Constructs an IndexOutOfBoundsException detail message. - * Of the many possible refactorings of the error handling code, - * this "outlining" performs best with both server and client VMs. - */ - private String outOfBoundsMsg(int index) { - return "Index: "+index+", Size: "+size; - } - - /** - * Removes from this list all of its elements that are contained in the - * specified collection. - * - * @param c collection containing elements to be removed from this list - * @return {@code true} if this list changed as a result of the call - * @throws ClassCastException if the class of an element of this list - * is incompatible with the specified collection - * (optional) - * @throws NullPointerException if this list contains a null element and the - * specified collection does not permit null elements - * (optional), - * or if the specified collection is null - * @see Collection#contains(Object) - */ - public boolean removeAll(Collection c) { - return batchRemove(c, false); - } - - /** - * Retains only the elements in this list that are contained in the - * specified collection. In other words, removes from this list all - * of its elements that are not contained in the specified collection. - * - * @param c collection containing elements to be retained in this list - * @return {@code true} if this list changed as a result of the call - * @throws ClassCastException if the class of an element of this list - * is incompatible with the specified collection - * (optional) - * @throws NullPointerException if this list contains a null element and the - * specified collection does not permit null elements - * (optional), - * or if the specified collection is null - * @see Collection#contains(Object) - */ - public boolean retainAll(Collection c) { - return batchRemove(c, true); - } - - private boolean batchRemove(Collection c, boolean complement) { - final Object[] elementData = this.elementData; - int r = 0, w = 0; - boolean modified = false; - try { - for (; r < size; r++) - if (c.contains(elementData[r]) == complement) - elementData[w++] = elementData[r]; - } finally { - // Preserve behavioral compatibility with AbstractCollection, - // even if c.contains() throws. - if (r != size) { - System.arraycopy(elementData, r, - elementData, w, - size - r); - w += size - r; - } - if (w != size) { - for (int i = w; i < size; i++) - elementData[i] = null; - modCount += size - w; - size = w; - modified = true; - } - } - return modified; - } - - /** - * Returns a list iterator over the elements in this list (in proper - * sequence), starting at the specified position in the list. - * The specified index indicates the first element that would be - * returned by an initial call to {@link ListIterator#next next}. - * An initial call to {@link ListIterator#previous previous} would - * return the element with the specified index minus one. - * - *

The returned list iterator is fail-fast. - * - * @throws IndexOutOfBoundsException {@inheritDoc} - */ - public ListIterator listIterator(int index) { - if (index < 0 || index > size) - throw new IndexOutOfBoundsException("Index: "+index); - return new ListItr(index); - } - - /** - * Returns a list iterator over the elements in this list (in proper - * sequence). - * - *

The returned list iterator is fail-fast. - * - * @see #listIterator(int) - */ - public ListIterator listIterator() { - return new ListItr(0); - } - - /** - * Returns an iterator over the elements in this list in proper sequence. - * - *

The returned iterator is fail-fast. - * - * @return an iterator over the elements in this list in proper sequence - */ - public Iterator iterator() { - return new Itr(); - } - - /** - * An optimized version of AbstractList.Itr - */ - private class Itr implements Iterator { - int cursor; // index of next element to return - int lastRet = -1; // index of last element returned; -1 if no such - int expectedModCount = modCount; - - public boolean hasNext() { - return cursor != size; - } - - @SuppressWarnings("unchecked") - public E next() { - checkForComodification(); - int i = cursor; - if (i >= size) - throw new NoSuchElementException(); - Object[] elementData = ArrayList.this.elementData; - if (i >= elementData.length) - throw new ConcurrentModificationException(); - cursor = i + 1; - return (E) elementData[lastRet = i]; - } - - public void remove() { - if (lastRet < 0) - throw new IllegalStateException(); - checkForComodification(); - - try { - ArrayList.this.remove(lastRet); - cursor = lastRet; - lastRet = -1; - expectedModCount = modCount; - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - final void checkForComodification() { - if (modCount != expectedModCount) - throw new ConcurrentModificationException(); - } - } - - /** - * An optimized version of AbstractList.ListItr - */ - private class ListItr extends Itr implements ListIterator { - ListItr(int index) { - super(); - cursor = index; - } - - public boolean hasPrevious() { - return cursor != 0; - } - - public int nextIndex() { - return cursor; - } - - public int previousIndex() { - return cursor - 1; - } - - @SuppressWarnings("unchecked") - public E previous() { - checkForComodification(); - int i = cursor - 1; - if (i < 0) - throw new NoSuchElementException(); - Object[] elementData = ArrayList.this.elementData; - if (i >= elementData.length) - throw new ConcurrentModificationException(); - cursor = i; - return (E) elementData[lastRet = i]; - } - - public void set(E e) { - if (lastRet < 0) - throw new IllegalStateException(); - checkForComodification(); - - try { - ArrayList.this.set(lastRet, e); - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - public void add(E e) { - checkForComodification(); - - try { - int i = cursor; - ArrayList.this.add(i, e); - cursor = i + 1; - lastRet = -1; - expectedModCount = modCount; - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - } - - /** - * Returns a view of the portion of this list between the specified - * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If - * {@code fromIndex} and {@code toIndex} are equal, the returned list is - * empty.) The returned list is backed by this list, so non-structural - * changes in the returned list are reflected in this list, and vice-versa. - * The returned list supports all of the optional list operations. - * - *

This method eliminates the need for explicit range operations (of - * the sort that commonly exist for arrays). Any operation that expects - * a list can be used as a range operation by passing a subList view - * instead of a whole list. For example, the following idiom - * removes a range of elements from a list: - *

-     *      list.subList(from, to).clear();
-     * 
- * Similar idioms may be constructed for {@link #indexOf(Object)} and - * {@link #lastIndexOf(Object)}, and all of the algorithms in the - * {@link Collections} class can be applied to a subList. - * - *

The semantics of the list returned by this method become undefined if - * the backing list (i.e., this list) is structurally modified in - * any way other than via the returned list. (Structural modifications are - * those that change the size of this list, or otherwise perturb it in such - * a fashion that iterations in progress may yield incorrect results.) - * - * @throws IndexOutOfBoundsException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - */ - public List subList(int fromIndex, int toIndex) { - subListRangeCheck(fromIndex, toIndex, size); - return new SubList(this, 0, fromIndex, toIndex); - } - - static void subListRangeCheck(int fromIndex, int toIndex, int size) { - if (fromIndex < 0) - throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); - if (toIndex > size) - throw new IndexOutOfBoundsException("toIndex = " + toIndex); - if (fromIndex > toIndex) - throw new IllegalArgumentException("fromIndex(" + fromIndex + - ") > toIndex(" + toIndex + ")"); - } - - private class SubList extends AbstractList implements RandomAccess { - private final AbstractList parent; - private final int parentOffset; - private final int offset; - int size; - - SubList(AbstractList parent, - int offset, int fromIndex, int toIndex) { - this.parent = parent; - this.parentOffset = fromIndex; - this.offset = offset + fromIndex; - this.size = toIndex - fromIndex; - this.modCount = ArrayList.this.modCount; - } - - public E set(int index, E e) { - rangeCheck(index); - checkForComodification(); - E oldValue = ArrayList.this.elementData(offset + index); - ArrayList.this.elementData[offset + index] = e; - return oldValue; - } - - public E get(int index) { - rangeCheck(index); - checkForComodification(); - return ArrayList.this.elementData(offset + index); - } - - public int size() { - checkForComodification(); - return this.size; - } - - public void add(int index, E e) { - rangeCheckForAdd(index); - checkForComodification(); - parent.add(parentOffset + index, e); - this.modCount = parent.modCount; - this.size++; - } - - public E remove(int index) { - rangeCheck(index); - checkForComodification(); - E result = parent.remove(parentOffset + index); - this.modCount = parent.modCount; - this.size--; - return result; - } - - protected void removeRange(int fromIndex, int toIndex) { - checkForComodification(); - parent.removeRange(parentOffset + fromIndex, - parentOffset + toIndex); - this.modCount = parent.modCount; - this.size -= toIndex - fromIndex; - } - - public boolean addAll(Collection c) { - return addAll(this.size, c); - } - - public boolean addAll(int index, Collection c) { - rangeCheckForAdd(index); - int cSize = c.size(); - if (cSize==0) - return false; - - checkForComodification(); - parent.addAll(parentOffset + index, c); - this.modCount = parent.modCount; - this.size += cSize; - return true; - } - - public Iterator iterator() { - return listIterator(); - } - - public ListIterator listIterator(final int index) { - checkForComodification(); - rangeCheckForAdd(index); - final int offset = this.offset; - - return new ListIterator() { - int cursor = index; - int lastRet = -1; - int expectedModCount = ArrayList.this.modCount; - - public boolean hasNext() { - return cursor != SubList.this.size; - } - - @SuppressWarnings("unchecked") - public E next() { - checkForComodification(); - int i = cursor; - if (i >= SubList.this.size) - throw new NoSuchElementException(); - Object[] elementData = ArrayList.this.elementData; - if (offset + i >= elementData.length) - throw new ConcurrentModificationException(); - cursor = i + 1; - return (E) elementData[offset + (lastRet = i)]; - } - - public boolean hasPrevious() { - return cursor != 0; - } - - @SuppressWarnings("unchecked") - public E previous() { - checkForComodification(); - int i = cursor - 1; - if (i < 0) - throw new NoSuchElementException(); - Object[] elementData = ArrayList.this.elementData; - if (offset + i >= elementData.length) - throw new ConcurrentModificationException(); - cursor = i; - return (E) elementData[offset + (lastRet = i)]; - } - - public int nextIndex() { - return cursor; - } - - public int previousIndex() { - return cursor - 1; - } - - public void remove() { - if (lastRet < 0) - throw new IllegalStateException(); - checkForComodification(); - - try { - SubList.this.remove(lastRet); - cursor = lastRet; - lastRet = -1; - expectedModCount = ArrayList.this.modCount; - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - public void set(E e) { - if (lastRet < 0) - throw new IllegalStateException(); - checkForComodification(); - - try { - ArrayList.this.set(offset + lastRet, e); - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - public void add(E e) { - checkForComodification(); - - try { - int i = cursor; - SubList.this.add(i, e); - cursor = i + 1; - lastRet = -1; - expectedModCount = ArrayList.this.modCount; - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - final void checkForComodification() { - if (expectedModCount != ArrayList.this.modCount) - throw new ConcurrentModificationException(); - } - }; - } - - public List subList(int fromIndex, int toIndex) { - subListRangeCheck(fromIndex, toIndex, size); - return new SubList(this, offset, fromIndex, toIndex); - } - - private void rangeCheck(int index) { - if (index < 0 || index >= this.size) - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - - private void rangeCheckForAdd(int index) { - if (index < 0 || index > this.size) - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - - private String outOfBoundsMsg(int index) { - return "Index: "+index+", Size: "+this.size; - } - - private void checkForComodification() { - if (ArrayList.this.modCount != this.modCount) - throw new ConcurrentModificationException(); - } - } -}