ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/ArrayList.java
Revision: 1.27
Committed: Sun May 18 23:59:57 2008 UTC (15 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.26: +0 -1 lines
Log Message:
Sync with OpenJDK; remove all @version tags

File Contents

# User Rev Content
1 dl 1.1 /*
2 jsr166 1.24 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
3     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 dl 1.1 *
5 jsr166 1.24 * This code is free software; you can redistribute it and/or modify it
6     * under the terms of the GNU General Public License version 2 only, as
7     * published by the Free Software Foundation. Sun designates this
8     * particular file as subject to the "Classpath" exception as provided
9     * by Sun in the LICENSE file that accompanied this code.
10     *
11     * This code is distributed in the hope that it will be useful, but WITHOUT
12     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13     * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14     * version 2 for more details (a copy is included in the LICENSE file that
15     * accompanied this code).
16     *
17     * You should have received a copy of the GNU General Public License version
18     * 2 along with this work; if not, write to the Free Software Foundation,
19     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20     *
21     * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22     * CA 95054 USA or visit www.sun.com if you need additional information or
23     * have any questions.
24 dl 1.1 */
25    
26     package java.util;
27    
28     /**
29     * Resizable-array implementation of the <tt>List</tt> interface. Implements
30     * all optional list operations, and permits all elements, including
31     * <tt>null</tt>. In addition to implementing the <tt>List</tt> interface,
32     * this class provides methods to manipulate the size of the array that is
33     * used internally to store the list. (This class is roughly equivalent to
34 jsr166 1.25 * <tt>Vector</tt>, except that it is unsynchronized.)
35 dl 1.1 *
36 jsr166 1.25 * <p>The <tt>size</tt>, <tt>isEmpty</tt>, <tt>get</tt>, <tt>set</tt>,
37 dl 1.1 * <tt>iterator</tt>, and <tt>listIterator</tt> operations run in constant
38     * time. The <tt>add</tt> operation runs in <i>amortized constant time</i>,
39     * that is, adding n elements requires O(n) time. All of the other operations
40     * run in linear time (roughly speaking). The constant factor is low compared
41 jsr166 1.25 * to that for the <tt>LinkedList</tt> implementation.
42 dl 1.1 *
43 jsr166 1.25 * <p>Each <tt>ArrayList</tt> instance has a <i>capacity</i>. The capacity is
44 dl 1.1 * the size of the array used to store the elements in the list. It is always
45     * at least as large as the list size. As elements are added to an ArrayList,
46     * its capacity grows automatically. The details of the growth policy are not
47     * specified beyond the fact that adding an element has constant amortized
48 jsr166 1.25 * time cost.
49 dl 1.1 *
50 jsr166 1.25 * <p>An application can increase the capacity of an <tt>ArrayList</tt> instance
51 dl 1.1 * before adding a large number of elements using the <tt>ensureCapacity</tt>
52     * operation. This may reduce the amount of incremental reallocation.
53     *
54     * <p><strong>Note that this implementation is not synchronized.</strong>
55     * If multiple threads access an <tt>ArrayList</tt> instance concurrently,
56     * and at least one of the threads modifies the list structurally, it
57     * <i>must</i> be synchronized externally. (A structural modification is
58     * any operation that adds or deletes one or more elements, or explicitly
59     * resizes the backing array; merely setting the value of an element is not
60     * a structural modification.) This is typically accomplished by
61     * synchronizing on some object that naturally encapsulates the list.
62     *
63     * If no such object exists, the list should be "wrapped" using the
64     * {@link Collections#synchronizedList Collections.synchronizedList}
65     * method. This is best done at creation time, to prevent accidental
66     * unsynchronized access to the list:<pre>
67     * List list = Collections.synchronizedList(new ArrayList(...));</pre>
68     *
69 jsr166 1.25 * <p><a name="fail-fast"/>
70     * The iterators returned by this class's {@link #iterator() iterator} and
71     * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
72     * if the list is structurally modified at any time after the iterator is
73     * created, in any way except through the iterator's own
74     * {@link ListIterator#remove() remove} or
75     * {@link ListIterator#add(Object) add} methods, the iterator will throw a
76     * {@link ConcurrentModificationException}. Thus, in the face of
77     * concurrent modification, the iterator fails quickly and cleanly, rather
78     * than risking arbitrary, non-deterministic behavior at an undetermined
79     * time in the future.
80 dl 1.1 *
81 jsr166 1.25 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
82 dl 1.1 * as it is, generally speaking, impossible to make any hard guarantees in the
83     * presence of unsynchronized concurrent modification. Fail-fast iterators
84 jsr166 1.25 * throw {@code ConcurrentModificationException} on a best-effort basis.
85 dl 1.1 * Therefore, it would be wrong to write a program that depended on this
86 jsr166 1.25 * exception for its correctness: <i>the fail-fast behavior of iterators
87     * should be used only to detect bugs.</i>
88 dl 1.1 *
89 jsr166 1.25 * <p>This class is a member of the
90 jsr166 1.21 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
91 dl 1.1 * Java Collections Framework</a>.
92     *
93     * @author Josh Bloch
94     * @author Neal Gafter
95 jsr166 1.26 * @see Collection
96     * @see List
97     * @see LinkedList
98     * @see Vector
99 dl 1.1 * @since 1.2
100     */
101    
102     public class ArrayList<E> extends AbstractList<E>
103     implements List<E>, RandomAccess, Cloneable, java.io.Serializable
104     {
105     private static final long serialVersionUID = 8683452581122892189L;
106    
107     /**
108     * The array buffer into which the elements of the ArrayList are stored.
109     * The capacity of the ArrayList is the length of this array buffer.
110     */
111     private transient Object[] elementData;
112    
113     /**
114     * The size of the ArrayList (the number of elements it contains).
115     *
116     * @serial
117     */
118     private int size;
119    
120     /**
121     * Constructs an empty list with the specified initial capacity.
122     *
123 jsr166 1.25 * @param initialCapacity the initial capacity of the list
124     * @exception IllegalArgumentException if the specified initial capacity
125     * is negative
126 dl 1.1 */
127     public ArrayList(int initialCapacity) {
128 jsr166 1.26 super();
129 dl 1.1 if (initialCapacity < 0)
130     throw new IllegalArgumentException("Illegal Capacity: "+
131     initialCapacity);
132 jsr166 1.26 this.elementData = new Object[initialCapacity];
133 dl 1.1 }
134    
135     /**
136     * Constructs an empty list with an initial capacity of ten.
137     */
138     public ArrayList() {
139 jsr166 1.26 this(10);
140 dl 1.1 }
141    
142     /**
143     * Constructs a list containing the elements of the specified
144     * collection, in the order they are returned by the collection's
145 jsr166 1.17 * iterator.
146 dl 1.1 *
147     * @param c the collection whose elements are to be placed into this list
148     * @throws NullPointerException if the specified collection is null
149     */
150     public ArrayList(Collection<? extends E> c) {
151 jsr166 1.26 elementData = c.toArray();
152     size = elementData.length;
153     // c.toArray might (incorrectly) not return Object[] (see 6260652)
154     if (elementData.getClass() != Object[].class)
155     elementData = Arrays.copyOf(elementData, size, Object[].class);
156 dl 1.2 }
157 jsr166 1.4
158 dl 1.1 /**
159     * Trims the capacity of this <tt>ArrayList</tt> instance to be the
160     * list's current size. An application can use this operation to minimize
161     * the storage of an <tt>ArrayList</tt> instance.
162     */
163     public void trimToSize() {
164 jsr166 1.26 modCount++;
165     int oldCapacity = elementData.length;
166     if (size < oldCapacity) {
167 dl 1.1 elementData = Arrays.copyOf(elementData, size);
168 jsr166 1.26 }
169 dl 1.1 }
170    
171     /**
172     * Increases the capacity of this <tt>ArrayList</tt> instance, if
173     * necessary, to ensure that it can hold at least the number of elements
174     * specified by the minimum capacity argument.
175     *
176 jsr166 1.25 * @param minCapacity the desired minimum capacity
177 dl 1.1 */
178     public void ensureCapacity(int minCapacity) {
179 jsr166 1.26 modCount++;
180     int oldCapacity = elementData.length;
181     if (minCapacity > oldCapacity) {
182     Object oldData[] = elementData;
183     int newCapacity = (oldCapacity * 3)/2 + 1;
184     if (newCapacity < minCapacity)
185     newCapacity = minCapacity;
186 jsr166 1.25 // minCapacity is usually close to size, so this is a win:
187     elementData = Arrays.copyOf(elementData, newCapacity);
188 jsr166 1.26 }
189 dl 1.1 }
190    
191     /**
192     * Returns the number of elements in this list.
193     *
194     * @return the number of elements in this list
195     */
196     public int size() {
197 jsr166 1.26 return size;
198 dl 1.1 }
199    
200     /**
201     * Returns <tt>true</tt> if this list contains no elements.
202     *
203     * @return <tt>true</tt> if this list contains no elements
204     */
205     public boolean isEmpty() {
206 jsr166 1.26 return size == 0;
207 dl 1.1 }
208    
209     /**
210     * Returns <tt>true</tt> if this list contains the specified element.
211     * More formally, returns <tt>true</tt> if and only if this list contains
212     * at least one element <tt>e</tt> such that
213     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
214     *
215     * @param o element whose presence in this list is to be tested
216     * @return <tt>true</tt> if this list contains the specified element
217     */
218     public boolean contains(Object o) {
219 jsr166 1.26 return indexOf(o) >= 0;
220 dl 1.1 }
221    
222     /**
223     * Returns the index of the first occurrence of the specified element
224     * in this list, or -1 if this list does not contain the element.
225     * More formally, returns the lowest index <tt>i</tt> such that
226     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
227     * or -1 if there is no such index.
228     */
229     public int indexOf(Object o) {
230 jsr166 1.26 if (o == null) {
231     for (int i = 0; i < size; i++)
232     if (elementData[i]==null)
233     return i;
234     } else {
235     for (int i = 0; i < size; i++)
236     if (o.equals(elementData[i]))
237     return i;
238     }
239     return -1;
240 dl 1.1 }
241    
242     /**
243     * Returns the index of the last occurrence of the specified element
244     * in this list, or -1 if this list does not contain the element.
245     * More formally, returns the highest index <tt>i</tt> such that
246     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
247     * or -1 if there is no such index.
248     */
249     public int lastIndexOf(Object o) {
250 jsr166 1.26 if (o == null) {
251     for (int i = size-1; i >= 0; i--)
252     if (elementData[i]==null)
253     return i;
254     } else {
255     for (int i = size-1; i >= 0; i--)
256     if (o.equals(elementData[i]))
257     return i;
258     }
259     return -1;
260 dl 1.1 }
261    
262     /**
263     * Returns a shallow copy of this <tt>ArrayList</tt> instance. (The
264     * elements themselves are not copied.)
265     *
266     * @return a clone of this <tt>ArrayList</tt> instance
267     */
268     public Object clone() {
269 jsr166 1.26 try {
270     @SuppressWarnings("unchecked")
271     ArrayList<E> v = (ArrayList<E>) super.clone();
272     v.elementData = Arrays.copyOf(elementData, size);
273     v.modCount = 0;
274     return v;
275     } catch (CloneNotSupportedException e) {
276     // this shouldn't happen, since we are Cloneable
277     throw new InternalError();
278     }
279 dl 1.1 }
280    
281     /**
282     * Returns an array containing all of the elements in this list
283     * in proper sequence (from first to last element).
284     *
285     * <p>The returned array will be "safe" in that no references to it are
286     * maintained by this list. (In other words, this method must allocate
287     * a new array). The caller is thus free to modify the returned array.
288     *
289     * <p>This method acts as bridge between array-based and collection-based
290     * APIs.
291     *
292     * @return an array containing all of the elements in this list in
293     * proper sequence
294     */
295     public Object[] toArray() {
296     return Arrays.copyOf(elementData, size);
297     }
298    
299     /**
300     * Returns an array containing all of the elements in this list in proper
301     * sequence (from first to last element); the runtime type of the returned
302     * array is that of the specified array. If the list fits in the
303     * specified array, it is returned therein. Otherwise, a new array is
304     * allocated with the runtime type of the specified array and the size of
305     * this list.
306     *
307     * <p>If the list fits in the specified array with room to spare
308     * (i.e., the array has more elements than the list), the element in
309     * the array immediately following the end of the collection is set to
310     * <tt>null</tt>. (This is useful in determining the length of the
311     * list <i>only</i> if the caller knows that the list does not contain
312     * any null elements.)
313     *
314     * @param a the array into which the elements of the list are to
315     * be stored, if it is big enough; otherwise, a new array of the
316     * same runtime type is allocated for this purpose.
317     * @return an array containing the elements of the list
318     * @throws ArrayStoreException if the runtime type of the specified array
319     * is not a supertype of the runtime type of every element in
320     * this list
321     * @throws NullPointerException if the specified array is null
322     */
323 jsr166 1.25 @SuppressWarnings("unchecked")
324 dl 1.1 public <T> T[] toArray(T[] a) {
325     if (a.length < size)
326     // Make a new array of a's runtime type, but my contents:
327     return (T[]) Arrays.copyOf(elementData, size, a.getClass());
328 jsr166 1.26 System.arraycopy(elementData, 0, a, 0, size);
329 dl 1.1 if (a.length > size)
330     a[size] = null;
331     return a;
332     }
333    
334     // Positional Access Operations
335    
336 jsr166 1.25 @SuppressWarnings("unchecked")
337     E elementData(int index) {
338 jsr166 1.26 return (E) elementData[index];
339 dl 1.1 }
340    
341     /**
342     * Returns the element at the specified position in this list.
343     *
344     * @param index index of the element to return
345     * @return the element at the specified position in this list
346     * @throws IndexOutOfBoundsException {@inheritDoc}
347     */
348     public E get(int index) {
349 jsr166 1.26 rangeCheck(index);
350 jsr166 1.25
351 jsr166 1.26 return elementData(index);
352 dl 1.1 }
353    
354     /**
355     * Replaces the element at the specified position in this list with
356     * the specified element.
357     *
358     * @param index index of the element to replace
359     * @param element element to be stored at the specified position
360     * @return the element previously at the specified position
361     * @throws IndexOutOfBoundsException {@inheritDoc}
362     */
363     public E set(int index, E element) {
364 jsr166 1.26 rangeCheck(index);
365 jsr166 1.25
366 jsr166 1.26 E oldValue = elementData(index);
367     elementData[index] = element;
368     return oldValue;
369 dl 1.1 }
370    
371     /**
372     * Appends the specified element to the end of this list.
373     *
374     * @param e element to be appended to this list
375     * @return <tt>true</tt> (as specified by {@link Collection#add})
376     */
377     public boolean add(E e) {
378 jsr166 1.26 ensureCapacity(size + 1); // Increments modCount!!
379     elementData[size++] = e;
380     return true;
381 dl 1.1 }
382    
383     /**
384     * Inserts the specified element at the specified position in this
385     * list. Shifts the element currently at that position (if any) and
386     * any subsequent elements to the right (adds one to their indices).
387     *
388     * @param index index at which the specified element is to be inserted
389     * @param element element to be inserted
390     * @throws IndexOutOfBoundsException {@inheritDoc}
391     */
392     public void add(int index, E element) {
393 jsr166 1.26 rangeCheckForAdd(index);
394 jsr166 1.25
395 jsr166 1.26 ensureCapacity(size+1); // Increments modCount!!
396     System.arraycopy(elementData, index, elementData, index + 1,
397     size - index);
398     elementData[index] = element;
399     size++;
400 dl 1.1 }
401    
402     /**
403     * Removes the element at the specified position in this list.
404     * Shifts any subsequent elements to the left (subtracts one from their
405     * indices).
406     *
407     * @param index the index of the element to be removed
408     * @return the element that was removed from the list
409     * @throws IndexOutOfBoundsException {@inheritDoc}
410     */
411     public E remove(int index) {
412 jsr166 1.26 rangeCheck(index);
413 jsr166 1.25
414 jsr166 1.26 modCount++;
415     E oldValue = elementData(index);
416 jsr166 1.25
417 jsr166 1.26 int numMoved = size - index - 1;
418     if (numMoved > 0)
419     System.arraycopy(elementData, index+1, elementData, index,
420     numMoved);
421     elementData[--size] = null; // Let gc do its work
422 jsr166 1.25
423 jsr166 1.26 return oldValue;
424 dl 1.1 }
425    
426     /**
427     * Removes the first occurrence of the specified element from this list,
428     * if it is present. If the list does not contain the element, it is
429     * unchanged. More formally, removes the element with the lowest index
430     * <tt>i</tt> such that
431     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
432     * (if such an element exists). Returns <tt>true</tt> if this list
433     * contained the specified element (or equivalently, if this list
434     * changed as a result of the call).
435     *
436     * @param o element to be removed from this list, if present
437     * @return <tt>true</tt> if this list contained the specified element
438     */
439     public boolean remove(Object o) {
440 jsr166 1.26 if (o == null) {
441     for (int index = 0; index < size; index++)
442     if (elementData[index] == null) {
443     fastRemove(index);
444     return true;
445     }
446     } else {
447 dl 1.1 for (int index = 0; index < size; index++)
448 jsr166 1.26 if (o.equals(elementData[index])) {
449     fastRemove(index);
450     return true;
451     }
452 dl 1.1 }
453 jsr166 1.26 return false;
454 dl 1.1 }
455    
456     /*
457     * Private remove method that skips bounds checking and does not
458     * return the value removed.
459     */
460     private void fastRemove(int index) {
461     modCount++;
462     int numMoved = size - index - 1;
463     if (numMoved > 0)
464     System.arraycopy(elementData, index+1, elementData, index,
465     numMoved);
466     elementData[--size] = null; // Let gc do its work
467     }
468    
469     /**
470     * Removes all of the elements from this list. The list will
471     * be empty after this call returns.
472     */
473     public void clear() {
474 jsr166 1.26 modCount++;
475 dl 1.1
476 jsr166 1.26 // Let gc do its work
477     for (int i = 0; i < size; i++)
478     elementData[i] = null;
479 dl 1.1
480 jsr166 1.26 size = 0;
481 dl 1.1 }
482    
483     /**
484     * Appends all of the elements in the specified collection to the end of
485     * this list, in the order that they are returned by the
486     * specified collection's Iterator. The behavior of this operation is
487     * undefined if the specified collection is modified while the operation
488     * is in progress. (This implies that the behavior of this call is
489     * undefined if the specified collection is this list, and this
490     * list is nonempty.)
491     *
492     * @param c collection containing elements to be added to this list
493     * @return <tt>true</tt> if this list changed as a result of the call
494     * @throws NullPointerException if the specified collection is null
495     */
496     public boolean addAll(Collection<? extends E> c) {
497 jsr166 1.26 Object[] a = c.toArray();
498 dl 1.1 int numNew = a.length;
499 jsr166 1.26 ensureCapacity(size + numNew); // Increments modCount
500 dl 1.1 System.arraycopy(a, 0, elementData, size, numNew);
501     size += numNew;
502 jsr166 1.26 return numNew != 0;
503 dl 1.1 }
504    
505     /**
506     * Inserts all of the elements in the specified collection into this
507     * list, starting at the specified position. Shifts the element
508     * currently at that position (if any) and any subsequent elements to
509     * the right (increases their indices). The new elements will appear
510     * in the list in the order that they are returned by the
511     * specified collection's iterator.
512     *
513     * @param index index at which to insert the first element from the
514     * specified collection
515     * @param c collection containing elements to be added to this list
516     * @return <tt>true</tt> if this list changed as a result of the call
517     * @throws IndexOutOfBoundsException {@inheritDoc}
518     * @throws NullPointerException if the specified collection is null
519     */
520     public boolean addAll(int index, Collection<? extends E> c) {
521 jsr166 1.26 rangeCheckForAdd(index);
522 dl 1.1
523 jsr166 1.26 Object[] a = c.toArray();
524     int numNew = a.length;
525     ensureCapacity(size + numNew); // Increments modCount
526    
527     int numMoved = size - index;
528     if (numMoved > 0)
529     System.arraycopy(elementData, index, elementData, index + numNew,
530     numMoved);
531 dl 1.1
532     System.arraycopy(a, 0, elementData, index, numNew);
533 jsr166 1.26 size += numNew;
534     return numNew != 0;
535 dl 1.1 }
536    
537     /**
538     * Removes from this list all of the elements whose index is between
539 jsr166 1.25 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
540 dl 1.1 * Shifts any succeeding elements to the left (reduces their index).
541 jsr166 1.25 * This call shortens the list by {@code (toIndex - fromIndex)} elements.
542     * (If {@code toIndex==fromIndex}, this operation has no effect.)
543 dl 1.1 *
544 jsr166 1.25 * @throws IndexOutOfBoundsException if {@code fromIndex} or
545     * {@code toIndex} is out of range
546     * ({@code fromIndex < 0 ||
547     * fromIndex >= size() ||
548     * toIndex > size() ||
549     * toIndex < fromIndex})
550 dl 1.1 */
551     protected void removeRange(int fromIndex, int toIndex) {
552 jsr166 1.26 modCount++;
553     int numMoved = size - toIndex;
554 dl 1.1 System.arraycopy(elementData, toIndex, elementData, fromIndex,
555     numMoved);
556    
557 jsr166 1.26 // Let gc do its work
558     int newSize = size - (toIndex-fromIndex);
559     while (size != newSize)
560     elementData[--size] = null;
561 dl 1.1 }
562    
563     /**
564 jsr166 1.25 * Checks if the given index is in range. If not, throws an appropriate
565     * runtime exception. This method does *not* check if the index is
566     * negative: It is always used immediately prior to an array access,
567     * which throws an ArrayIndexOutOfBoundsException if index is negative.
568     */
569     private void rangeCheck(int index) {
570     if (index >= size)
571     throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
572     }
573    
574     /**
575     * A version of rangeCheck used by add and addAll.
576     */
577     private void rangeCheckForAdd(int index) {
578 jsr166 1.26 if (index > size || index < 0)
579     throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
580 jsr166 1.25 }
581    
582     /**
583     * Constructs an IndexOutOfBoundsException detail message.
584     * Of the many possible refactorings of the error handling code,
585     * this "outlining" performs best with both server and client VMs.
586     */
587     private String outOfBoundsMsg(int index) {
588 jsr166 1.26 return "Index: "+index+", Size: "+size;
589 jsr166 1.25 }
590    
591     /**
592     * Removes from this list all of its elements that are contained in the
593     * specified collection.
594     *
595     * @param c collection containing elements to be removed from this list
596     * @return {@code true} if this list changed as a result of the call
597     * @throws ClassCastException if the class of an element of this list
598     * is incompatible with the specified collection (optional)
599     * @throws NullPointerException if this list contains a null element and the
600     * specified collection does not permit null elements (optional),
601     * or if the specified collection is null
602     * @see Collection#contains(Object)
603     */
604     public boolean removeAll(Collection<?> c) {
605 jsr166 1.26 return batchRemove(c, false);
606 jsr166 1.25 }
607    
608     /**
609     * Retains only the elements in this list that are contained in the
610     * specified collection. In other words, removes from this list all
611     * of its elements that are not contained in the specified collection.
612     *
613     * @param c collection containing elements to be retained in this list
614     * @return {@code true} if this list changed as a result of the call
615     * @throws ClassCastException if the class of an element of this list
616     * is incompatible with the specified collection (optional)
617     * @throws NullPointerException if this list contains a null element and the
618     * specified collection does not permit null elements (optional),
619     * or if the specified collection is null
620     * @see Collection#contains(Object)
621     */
622     public boolean retainAll(Collection<?> c) {
623 jsr166 1.26 return batchRemove(c, true);
624 jsr166 1.25 }
625    
626     private boolean batchRemove(Collection<?> c, boolean complement) {
627 jsr166 1.26 final Object[] elementData = this.elementData;
628     int r = 0, w = 0;
629     boolean modified = false;
630     try {
631     for (; r < size; r++)
632     if (c.contains(elementData[r]) == complement)
633     elementData[w++] = elementData[r];
634     } finally {
635     // Preserve behavioral compatibility with AbstractCollection,
636     // even if c.contains() throws.
637     if (r != size) {
638     System.arraycopy(elementData, r,
639     elementData, w,
640     size - r);
641     w += size - r;
642     }
643     if (w != size) {
644     for (int i = w; i < size; i++)
645     elementData[i] = null;
646     modCount += size - w;
647     size = w;
648     modified = true;
649     }
650     }
651     return modified;
652 jsr166 1.25 }
653    
654     /**
655 dl 1.1 * Save the state of the <tt>ArrayList</tt> instance to a stream (that
656     * is, serialize it).
657     *
658     * @serialData The length of the array backing the <tt>ArrayList</tt>
659     * instance is emitted (int), followed by all of its elements
660     * (each an <tt>Object</tt>) in the proper order.
661     */
662     private void writeObject(java.io.ObjectOutputStream s)
663     throws java.io.IOException{
664 jsr166 1.26 // Write out element count, and any hidden stuff
665     int expectedModCount = modCount;
666     s.defaultWriteObject();
667 dl 1.1
668     // Write out array length
669     s.writeInt(elementData.length);
670    
671 jsr166 1.26 // Write out all elements in the proper order.
672     for (int i=0; i<size; i++)
673 dl 1.1 s.writeObject(elementData[i]);
674    
675 jsr166 1.26 if (modCount != expectedModCount) {
676 dl 1.1 throw new ConcurrentModificationException();
677     }
678    
679     }
680    
681     /**
682     * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
683     * deserialize it).
684     */
685     private void readObject(java.io.ObjectInputStream s)
686     throws java.io.IOException, ClassNotFoundException {
687 jsr166 1.26 // Read in size, and any hidden stuff
688     s.defaultReadObject();
689 dl 1.1
690     // Read in array length and allocate array
691     int arrayLength = s.readInt();
692     Object[] a = elementData = new Object[arrayLength];
693    
694 jsr166 1.26 // Read in all elements in the proper order.
695     for (int i=0; i<size; i++)
696 dl 1.1 a[i] = s.readObject();
697     }
698 jsr166 1.25
699     /**
700     * Returns a list iterator over the elements in this list (in proper
701     * sequence), starting at the specified position in the list.
702     * The specified index indicates the first element that would be
703     * returned by an initial call to {@link ListIterator#next next}.
704     * An initial call to {@link ListIterator#previous previous} would
705     * return the element with the specified index minus one.
706     *
707     * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
708     *
709     * @throws IndexOutOfBoundsException {@inheritDoc}
710     */
711     public ListIterator<E> listIterator(int index) {
712 jsr166 1.26 if (index < 0 || index > size)
713 jsr166 1.25 throw new IndexOutOfBoundsException("Index: "+index);
714 jsr166 1.26 return new ListItr(index);
715 jsr166 1.25 }
716    
717     /**
718     * Returns a list iterator over the elements in this list (in proper
719     * sequence).
720     *
721     * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
722     *
723     * @see #listIterator(int)
724     */
725     public ListIterator<E> listIterator() {
726 jsr166 1.26 return new ListItr(0);
727 jsr166 1.25 }
728    
729     /**
730     * Returns an iterator over the elements in this list in proper sequence.
731     *
732     * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
733     *
734     * @return an iterator over the elements in this list in proper sequence
735     */
736     public Iterator<E> iterator() {
737 jsr166 1.26 return new Itr();
738 jsr166 1.25 }
739    
740     /**
741     * An optimized version of AbstractList.Itr
742     */
743     private class Itr implements Iterator<E> {
744 jsr166 1.26 int cursor; // index of next element to return
745     int lastRet = -1; // index of last element returned; -1 if no such
746     int expectedModCount = modCount;
747 jsr166 1.25
748 jsr166 1.26 public boolean hasNext() {
749 jsr166 1.25 return cursor != size;
750 jsr166 1.26 }
751    
752     @SuppressWarnings("unchecked")
753     public E next() {
754     checkForComodification();
755     int i = cursor;
756     if (i >= size)
757     throw new NoSuchElementException();
758     Object[] elementData = ArrayList.this.elementData;
759     if (i >= elementData.length)
760     throw new ConcurrentModificationException();
761     cursor = i + 1;
762     return (E) elementData[lastRet = i];
763     }
764 jsr166 1.25
765 jsr166 1.26 public void remove() {
766     if (lastRet < 0)
767     throw new IllegalStateException();
768 jsr166 1.25 checkForComodification();
769 jsr166 1.26
770     try {
771     ArrayList.this.remove(lastRet);
772     cursor = lastRet;
773     lastRet = -1;
774     expectedModCount = modCount;
775     } catch (IndexOutOfBoundsException ex) {
776     throw new ConcurrentModificationException();
777     }
778     }
779    
780     final void checkForComodification() {
781     if (modCount != expectedModCount)
782     throw new ConcurrentModificationException();
783     }
784 jsr166 1.25 }
785    
786     /**
787     * An optimized version of AbstractList.ListItr
788     */
789     private class ListItr extends Itr implements ListIterator<E> {
790 jsr166 1.26 ListItr(int index) {
791     super();
792     cursor = index;
793     }
794    
795     public boolean hasPrevious() {
796     return cursor != 0;
797     }
798 jsr166 1.25
799 jsr166 1.26 public int nextIndex() {
800     return cursor;
801     }
802    
803     public int previousIndex() {
804     return cursor - 1;
805     }
806    
807     @SuppressWarnings("unchecked")
808 jsr166 1.25 public E previous() {
809 jsr166 1.26 checkForComodification();
810     int i = cursor - 1;
811     if (i < 0)
812     throw new NoSuchElementException();
813     Object[] elementData = ArrayList.this.elementData;
814     if (i >= elementData.length)
815     throw new ConcurrentModificationException();
816     cursor = i;
817     return (E) elementData[lastRet = i];
818     }
819    
820     public void set(E e) {
821     if (lastRet < 0)
822     throw new IllegalStateException();
823     checkForComodification();
824    
825     try {
826     ArrayList.this.set(lastRet, e);
827     } catch (IndexOutOfBoundsException ex) {
828     throw new ConcurrentModificationException();
829     }
830     }
831    
832     public void add(E e) {
833     checkForComodification();
834    
835     try {
836     int i = cursor;
837     ArrayList.this.add(i, e);
838     cursor = i + 1;
839     lastRet = -1;
840     expectedModCount = modCount;
841     } catch (IndexOutOfBoundsException ex) {
842     throw new ConcurrentModificationException();
843     }
844     }
845 jsr166 1.25 }
846    
847     /**
848     * Returns a view of the portion of this list between the specified
849     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If
850     * {@code fromIndex} and {@code toIndex} are equal, the returned list is
851     * empty.) The returned list is backed by this list, so non-structural
852     * changes in the returned list are reflected in this list, and vice-versa.
853     * The returned list supports all of the optional list operations.
854     *
855     * <p>This method eliminates the need for explicit range operations (of
856     * the sort that commonly exist for arrays). Any operation that expects
857     * a list can be used as a range operation by passing a subList view
858     * instead of a whole list. For example, the following idiom
859     * removes a range of elements from a list:
860     * <pre>
861     * list.subList(from, to).clear();
862     * </pre>
863     * Similar idioms may be constructed for {@link #indexOf(Object)} and
864     * {@link #lastIndexOf(Object)}, and all of the algorithms in the
865     * {@link Collections} class can be applied to a subList.
866     *
867     * <p>The semantics of the list returned by this method become undefined if
868     * the backing list (i.e., this list) is <i>structurally modified</i> in
869     * any way other than via the returned list. (Structural modifications are
870     * those that change the size of this list, or otherwise perturb it in such
871     * a fashion that iterations in progress may yield incorrect results.)
872     *
873     * @throws IndexOutOfBoundsException {@inheritDoc}
874     * @throws IllegalArgumentException {@inheritDoc}
875     */
876     public List<E> subList(int fromIndex, int toIndex) {
877 jsr166 1.26 subListRangeCheck(fromIndex, toIndex, size);
878 jsr166 1.25 return new SubList(this, 0, fromIndex, toIndex);
879     }
880    
881     static void subListRangeCheck(int fromIndex, int toIndex, int size) {
882 jsr166 1.26 if (fromIndex < 0)
883     throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
884     if (toIndex > size)
885     throw new IndexOutOfBoundsException("toIndex = " + toIndex);
886     if (fromIndex > toIndex)
887     throw new IllegalArgumentException("fromIndex(" + fromIndex +
888     ") > toIndex(" + toIndex + ")");
889 jsr166 1.25 }
890    
891     private class SubList extends AbstractList<E> implements RandomAccess {
892 jsr166 1.26 private final AbstractList<E> parent;
893     private final int parentOffset;
894     private final int offset;
895     private int size;
896    
897     SubList(AbstractList<E> parent,
898     int offset, int fromIndex, int toIndex) {
899     this.parent = parent;
900     this.parentOffset = fromIndex;
901     this.offset = offset + fromIndex;
902     this.size = toIndex - fromIndex;
903     this.modCount = ArrayList.this.modCount;
904     }
905    
906     public E set(int index, E e) {
907     rangeCheck(index);
908     checkForComodification();
909     E oldValue = ArrayList.this.elementData(offset + index);
910     ArrayList.this.elementData[offset + index] = e;
911     return oldValue;
912     }
913    
914     public E get(int index) {
915     rangeCheck(index);
916     checkForComodification();
917     return ArrayList.this.elementData(offset + index);
918     }
919    
920     public int size() {
921     checkForComodification();
922     return this.size;
923     }
924    
925     public void add(int index, E e) {
926     rangeCheckForAdd(index);
927     checkForComodification();
928     parent.add(parentOffset + index, e);
929     this.modCount = parent.modCount;
930     this.size++;
931     }
932    
933     public E remove(int index) {
934     rangeCheck(index);
935     checkForComodification();
936     E result = parent.remove(parentOffset + index);
937     this.modCount = parent.modCount;
938     this.size--;
939     return result;
940     }
941    
942     protected void removeRange(int fromIndex, int toIndex) {
943     checkForComodification();
944     parent.removeRange(parentOffset + fromIndex,
945     parentOffset + toIndex);
946     this.modCount = parent.modCount;
947     this.size -= toIndex - fromIndex;
948     }
949    
950     public boolean addAll(Collection<? extends E> c) {
951     return addAll(this.size, c);
952     }
953    
954     public boolean addAll(int index, Collection<? extends E> c) {
955     rangeCheckForAdd(index);
956     int cSize = c.size();
957     if (cSize==0)
958     return false;
959    
960     checkForComodification();
961     parent.addAll(parentOffset + index, c);
962     this.modCount = parent.modCount;
963     this.size += cSize;
964     return true;
965     }
966    
967     public Iterator<E> iterator() {
968     return listIterator();
969     }
970    
971     public ListIterator<E> listIterator(final int index) {
972     checkForComodification();
973     rangeCheckForAdd(index);
974    
975     return new ListIterator<E>() {
976     int cursor = index;
977     int lastRet = -1;
978     int expectedModCount = ArrayList.this.modCount;
979    
980     public boolean hasNext() {
981     return cursor != SubList.this.size;
982     }
983    
984     @SuppressWarnings("unchecked")
985     public E next() {
986     checkForComodification();
987     int i = cursor;
988     if (i >= SubList.this.size)
989     throw new NoSuchElementException();
990     Object[] elementData = ArrayList.this.elementData;
991     if (offset + i >= elementData.length)
992     throw new ConcurrentModificationException();
993     cursor = i + 1;
994     return (E) elementData[offset + (lastRet = i)];
995     }
996    
997     public boolean hasPrevious() {
998     return cursor != 0;
999     }
1000    
1001     @SuppressWarnings("unchecked")
1002     public E previous() {
1003     checkForComodification();
1004     int i = cursor - 1;
1005     if (i < 0)
1006     throw new NoSuchElementException();
1007     Object[] elementData = ArrayList.this.elementData;
1008     if (offset + i >= elementData.length)
1009     throw new ConcurrentModificationException();
1010     cursor = i;
1011     return (E) elementData[offset + (lastRet = i)];
1012     }
1013    
1014     public int nextIndex() {
1015     return cursor;
1016     }
1017    
1018     public int previousIndex() {
1019     return cursor - 1;
1020     }
1021    
1022     public void remove() {
1023     if (lastRet < 0)
1024     throw new IllegalStateException();
1025     checkForComodification();
1026    
1027     try {
1028     SubList.this.remove(lastRet);
1029     cursor = lastRet;
1030     lastRet = -1;
1031     expectedModCount = ArrayList.this.modCount;
1032     } catch (IndexOutOfBoundsException ex) {
1033     throw new ConcurrentModificationException();
1034     }
1035     }
1036    
1037     public void set(E e) {
1038     if (lastRet < 0)
1039     throw new IllegalStateException();
1040     checkForComodification();
1041    
1042     try {
1043     ArrayList.this.set(offset + lastRet, e);
1044     } catch (IndexOutOfBoundsException ex) {
1045     throw new ConcurrentModificationException();
1046     }
1047     }
1048    
1049     public void add(E e) {
1050     checkForComodification();
1051    
1052     try {
1053     int i = cursor;
1054     SubList.this.add(i, e);
1055     cursor = i + 1;
1056     lastRet = -1;
1057     expectedModCount = ArrayList.this.modCount;
1058     } catch (IndexOutOfBoundsException ex) {
1059     throw new ConcurrentModificationException();
1060     }
1061     }
1062    
1063     final void checkForComodification() {
1064     if (expectedModCount != ArrayList.this.modCount)
1065     throw new ConcurrentModificationException();
1066     }
1067     };
1068     }
1069    
1070     public List<E> subList(int fromIndex, int toIndex) {
1071     subListRangeCheck(fromIndex, toIndex, size);
1072     return new SubList(this, offset, fromIndex, toIndex);
1073     }
1074    
1075     private void rangeCheck(int index) {
1076     if (index < 0 || index >= this.size)
1077     throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1078     }
1079    
1080     private void rangeCheckForAdd(int index) {
1081     if (index < 0 || index > this.size)
1082     throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1083     }
1084    
1085     private String outOfBoundsMsg(int index) {
1086     return "Index: "+index+", Size: "+this.size;
1087     }
1088    
1089     private void checkForComodification() {
1090     if (ArrayList.this.modCount != this.modCount)
1091     throw new ConcurrentModificationException();
1092     }
1093 jsr166 1.25 }
1094 dl 1.1 }