ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/ArrayList.java
(Generate patch)

Comparing jsr166/src/main/java/util/ArrayList.java (file contents):
Revision 1.24 by jsr166, Sun May 20 07:54:01 2007 UTC vs.
Revision 1.25 by jsr166, Tue Sep 11 15:38:02 2007 UTC

# Line 31 | Line 31 | package java.util;
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 < * <tt>Vector</tt>, except that it is unsynchronized.)<p>
34 > * <tt>Vector</tt>, except that it is unsynchronized.)
35   *
36 < * The <tt>size</tt>, <tt>isEmpty</tt>, <tt>get</tt>, <tt>set</tt>,
36 > * <p>The <tt>size</tt>, <tt>isEmpty</tt>, <tt>get</tt>, <tt>set</tt>,
37   * <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 < * to that for the <tt>LinkedList</tt> implementation.<p>
41 > * to that for the <tt>LinkedList</tt> implementation.
42   *
43 < * Each <tt>ArrayList</tt> instance has a <i>capacity</i>.  The capacity is
43 > * <p>Each <tt>ArrayList</tt> instance has a <i>capacity</i>.  The capacity is
44   * 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 < * time cost.<p>
48 > * time cost.
49   *
50 < * An application can increase the capacity of an <tt>ArrayList</tt> instance
50 > * <p>An application can increase the capacity of an <tt>ArrayList</tt> instance
51   * before adding a large number of elements using the <tt>ensureCapacity</tt>
52   * operation.  This may reduce the amount of incremental reallocation.
53   *
# Line 66 | Line 66 | package java.util;
66   * unsynchronized access to the list:<pre>
67   *   List list = Collections.synchronizedList(new ArrayList(...));</pre>
68   *
69 < * <p>The iterators returned by this class's <tt>iterator</tt> and
70 < * <tt>listIterator</tt> methods are <i>fail-fast</i>: if the list is
71 < * structurally modified at any time after the iterator is created, in any way
72 < * except through the iterator's own <tt>remove</tt> or <tt>add</tt> methods,
73 < * the iterator will throw a {@link ConcurrentModificationException}.  Thus, in
74 < * the face of concurrent modification, the iterator fails quickly and cleanly,
75 < * rather than risking arbitrary, non-deterministic behavior at an undetermined
76 < * time in the future.<p>
69 > * <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   *
81 < * Note that the fail-fast behavior of an iterator cannot be guaranteed
81 > * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
82   * as it is, generally speaking, impossible to make any hard guarantees in the
83   * presence of unsynchronized concurrent modification.  Fail-fast iterators
84 < * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
84 > * throw {@code ConcurrentModificationException} on a best-effort basis.
85   * Therefore, it would be wrong to write a program that depended on this
86 < * exception for its correctness: <i>the fail-fast behavior of iterators
87 < * should be used only to detect bugs.</i><p>
86 > * exception for its correctness:  <i>the fail-fast behavior of iterators
87 > * should be used only to detect bugs.</i>
88   *
89 < * This class is a member of the
89 > * <p>This class is a member of the
90   * <a href="{@docRoot}/../technotes/guides/collections/index.html">
91   * Java Collections Framework</a>.
92   *
# Line 118 | Line 121 | public class ArrayList<E> extends Abstra
121      /**
122       * Constructs an empty list with the specified initial capacity.
123       *
124 <     * @param initialCapacity the initial capacity of the list
125 <     * @throws IllegalArgumentException if the specified initial capacity
126 <     *         is negative
124 >     * @param   initialCapacity   the initial capacity of the list
125 >     * @exception IllegalArgumentException if the specified initial capacity
126 >     *            is negative
127       */
128      public ArrayList(int initialCapacity) {
129          super();
# Line 171 | Line 174 | public class ArrayList<E> extends Abstra
174       * necessary, to ensure that it can hold at least the number of elements
175       * specified by the minimum capacity argument.
176       *
177 <     * @param minCapacity the desired minimum capacity
177 >     * @param   minCapacity   the desired minimum capacity
178       */
179      public void ensureCapacity(int minCapacity) {
180          modCount++;
178        if (minCapacity > elementData.length)
179            growArray(minCapacity);
180    }
181
182    /**
183     * Increases the capacity of the array.
184     *
185     * @param minCapacity the desired minimum capacity
186     */
187    private void growArray(int minCapacity) {
188        if (minCapacity < 0) // overflow
189            throw new OutOfMemoryError();
181          int oldCapacity = elementData.length;
182 <        // Double size if small; else grow by 50%
183 <        int newCapacity = ((oldCapacity < 64) ?
184 <                           ((oldCapacity + 1) * 2) :
185 <                           ((oldCapacity / 2) * 3));
186 <        if (newCapacity < 0) // overflow
187 <            newCapacity = Integer.MAX_VALUE;
188 <        if (newCapacity < minCapacity)
189 <            newCapacity = minCapacity;
199 <        elementData = Arrays.copyOf(elementData, newCapacity);
182 >        if (minCapacity > oldCapacity) {
183 >            Object oldData[] = elementData;
184 >            int newCapacity = (oldCapacity * 3)/2 + 1;
185 >            if (newCapacity < minCapacity)
186 >                newCapacity = minCapacity;
187 >            // minCapacity is usually close to size, so this is a win:
188 >            elementData = Arrays.copyOf(elementData, newCapacity);
189 >        }
190      }
191  
192      /**
# Line 278 | Line 268 | public class ArrayList<E> extends Abstra
268       */
269      public Object clone() {
270          try {
271 <            ArrayList<E> v = (ArrayList<E>) super.clone();
271 >            @SuppressWarnings("unchecked")
272 >                ArrayList<E> v = (ArrayList<E>) super.clone();
273              v.elementData = Arrays.copyOf(elementData, size);
274              v.modCount = 0;
275              return v;
# Line 330 | Line 321 | public class ArrayList<E> extends Abstra
321       *         this list
322       * @throws NullPointerException if the specified array is null
323       */
324 +    @SuppressWarnings("unchecked")
325      public <T> T[] toArray(T[] a) {
326          if (a.length < size)
327              // Make a new array of a's runtime type, but my contents:
# Line 342 | Line 334 | public class ArrayList<E> extends Abstra
334  
335      // Positional Access Operations
336  
337 <    /**
338 <     * Throws an appropriate exception for indexing errors.
339 <     */
348 <    private static void indexOutOfBounds(int i, int s) {
349 <        throw new IndexOutOfBoundsException("Index: " + i + ", Size: " + s);
337 >    @SuppressWarnings("unchecked")
338 >    E elementData(int index) {
339 >        return (E) elementData[index];
340      }
341  
342      /**
# Line 357 | Line 347 | public class ArrayList<E> extends Abstra
347       * @throws IndexOutOfBoundsException {@inheritDoc}
348       */
349      public E get(int index) {
350 <        if (index >= size)
351 <            indexOutOfBounds(index, size);
352 <        return (E) elementData[index];
350 >        rangeCheck(index);
351 >
352 >        return elementData(index);
353      }
354  
355      /**
# Line 372 | Line 362 | public class ArrayList<E> extends Abstra
362       * @throws IndexOutOfBoundsException {@inheritDoc}
363       */
364      public E set(int index, E element) {
365 <        if (index >= size)
366 <            indexOutOfBounds(index, size);
367 <        E oldValue = (E) elementData[index];
365 >        rangeCheck(index);
366 >
367 >        E oldValue = elementData(index);
368          elementData[index] = element;
369          return oldValue;
370      }
# Line 386 | Line 376 | public class ArrayList<E> extends Abstra
376       * @return <tt>true</tt> (as specified by {@link Collection#add})
377       */
378      public boolean add(E e) {
379 <        modCount++;
380 <        int s = size;
391 <        if (s >= elementData.length)
392 <            growArray(s + 1);
393 <        elementData[s] = e;
394 <        size = s + 1;
379 >        ensureCapacity(size + 1);  // Increments modCount!!
380 >        elementData[size++] = e;
381          return true;
382      }
383  
# Line 405 | Line 391 | public class ArrayList<E> extends Abstra
391       * @throws IndexOutOfBoundsException {@inheritDoc}
392       */
393      public void add(int index, E element) {
394 <        int s = size;
395 <        if (index > s || index < 0)
396 <            indexOutOfBounds(index, s);
397 <        modCount++;
398 <        if (s >= elementData.length)
413 <            growArray(s + 1);
414 <        System.arraycopy(elementData, index,
415 <                         elementData, index + 1, s - index);
394 >        rangeCheckForAdd(index);
395 >
396 >        ensureCapacity(size+1);  // Increments modCount!!
397 >        System.arraycopy(elementData, index, elementData, index + 1,
398 >                         size - index);
399          elementData[index] = element;
400 <        size = s + 1;
400 >        size++;
401      }
402  
403      /**
# Line 427 | Line 410 | public class ArrayList<E> extends Abstra
410       * @throws IndexOutOfBoundsException {@inheritDoc}
411       */
412      public E remove(int index) {
413 <        int s = size - 1;
414 <        if (index > s)
432 <            indexOutOfBounds(index, size);
413 >        rangeCheck(index);
414 >
415          modCount++;
416 <        E oldValue = (E) elementData[index];
417 <        int numMoved = s - index;
416 >        E oldValue = elementData(index);
417 >
418 >        int numMoved = size - index - 1;
419          if (numMoved > 0)
420 <            System.arraycopy(elementData, index + 1,
421 <                             elementData, index, numMoved);
422 <        elementData[s] = null;
423 <        size = s;
420 >            System.arraycopy(elementData, index+1, elementData, index,
421 >                             numMoved);
422 >        elementData[--size] = null; // Let gc do its work
423 >
424          return oldValue;
425      }
426  
# Line 536 | Line 519 | public class ArrayList<E> extends Abstra
519       * @throws NullPointerException if the specified collection is null
520       */
521      public boolean addAll(int index, Collection<? extends E> c) {
522 <        if (index > size || index < 0)
540 <            indexOutOfBounds(index, size);
522 >        rangeCheckForAdd(index);
523  
524          Object[] a = c.toArray();
525          int numNew = a.length;
# Line 555 | Line 537 | public class ArrayList<E> extends Abstra
537  
538      /**
539       * Removes from this list all of the elements whose index is between
540 <     * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
540 >     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
541       * Shifts any succeeding elements to the left (reduces their index).
542 <     * This call shortens the list by <tt>(toIndex - fromIndex)</tt> elements.
543 <     * (If <tt>toIndex==fromIndex</tt>, this operation has no effect.)
542 >     * This call shortens the list by {@code (toIndex - fromIndex)} elements.
543 >     * (If {@code toIndex==fromIndex}, this operation has no effect.)
544       *
545 <     * @param fromIndex index of first element to be removed
546 <     * @param toIndex index after last element to be removed
547 <     * @throws IndexOutOfBoundsException if fromIndex or toIndex out of
548 <     *              range (fromIndex &lt; 0 || fromIndex &gt;= size() || toIndex
549 <     *              &gt; size() || toIndex &lt; fromIndex)
545 >     * @throws IndexOutOfBoundsException if {@code fromIndex} or
546 >     *         {@code toIndex} is out of range
547 >     *         ({@code fromIndex < 0 ||
548 >     *          fromIndex >= size() ||
549 >     *          toIndex > size() ||
550 >     *          toIndex < fromIndex})
551       */
552      protected void removeRange(int fromIndex, int toIndex) {
553          modCount++;
# Line 579 | Line 562 | public class ArrayList<E> extends Abstra
562      }
563  
564      /**
565 +     * Checks if the given index is in range.  If not, throws an appropriate
566 +     * runtime exception.  This method does *not* check if the index is
567 +     * negative: It is always used immediately prior to an array access,
568 +     * which throws an ArrayIndexOutOfBoundsException if index is negative.
569 +     */
570 +    private void rangeCheck(int index) {
571 +        if (index >= size)
572 +            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
573 +    }
574 +
575 +    /**
576 +     * A version of rangeCheck used by add and addAll.
577 +     */
578 +    private void rangeCheckForAdd(int index) {
579 +        if (index > size || index < 0)
580 +            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
581 +    }
582 +
583 +    /**
584 +     * Constructs an IndexOutOfBoundsException detail message.
585 +     * Of the many possible refactorings of the error handling code,
586 +     * this "outlining" performs best with both server and client VMs.
587 +     */
588 +    private String outOfBoundsMsg(int index) {
589 +        return "Index: "+index+", Size: "+size;
590 +    }
591 +
592 +    /**
593 +     * Removes from this list all of its elements that are contained in the
594 +     * specified collection.
595 +     *
596 +     * @param c collection containing elements to be removed from this list
597 +     * @return {@code true} if this list changed as a result of the call
598 +     * @throws ClassCastException if the class of an element of this list
599 +     *         is incompatible with the specified collection (optional)
600 +     * @throws NullPointerException if this list contains a null element and the
601 +     *         specified collection does not permit null elements (optional),
602 +     *         or if the specified collection is null
603 +     * @see Collection#contains(Object)
604 +     */
605 +    public boolean removeAll(Collection<?> c) {
606 +        return batchRemove(c, false);
607 +    }
608 +
609 +    /**
610 +     * Retains only the elements in this list that are contained in the
611 +     * specified collection.  In other words, removes from this list all
612 +     * of its elements that are not contained in the specified collection.
613 +     *
614 +     * @param c collection containing elements to be retained in this list
615 +     * @return {@code true} if this list changed as a result of the call
616 +     * @throws ClassCastException if the class of an element of this list
617 +     *         is incompatible with the specified collection (optional)
618 +     * @throws NullPointerException if this list contains a null element and the
619 +     *         specified collection does not permit null elements (optional),
620 +     *         or if the specified collection is null
621 +     * @see Collection#contains(Object)
622 +     */
623 +    public boolean retainAll(Collection<?> c) {
624 +        return batchRemove(c, true);
625 +    }
626 +
627 +    private boolean batchRemove(Collection<?> c, boolean complement) {
628 +        final Object[] elementData = this.elementData;
629 +        int r = 0, w = 0;
630 +        boolean modified = false;
631 +        try {
632 +            for (; r < size; r++)
633 +                if (c.contains(elementData[r]) == complement)
634 +                    elementData[w++] = elementData[r];
635 +        } finally {
636 +            // Preserve behavioral compatibility with AbstractCollection,
637 +            // even if c.contains() throws.
638 +            if (r != size) {
639 +                System.arraycopy(elementData, r,
640 +                                 elementData, w,
641 +                                 size - r);
642 +                w += size - r;
643 +            }
644 +            if (w != size) {
645 +                for (int i = w; i < size; i++)
646 +                    elementData[i] = null;
647 +                modCount += size - w;
648 +                size = w;
649 +                modified = true;
650 +            }
651 +        }
652 +        return modified;
653 +    }
654 +
655 +    /**
656       * Save the state of the <tt>ArrayList</tt> instance to a stream (that
657       * is, serialize it).
658       *
# Line 599 | Line 673 | public class ArrayList<E> extends Abstra
673          for (int i=0; i<size; i++)
674              s.writeObject(elementData[i]);
675  
676 <        if (expectedModCount != modCount) {
676 >        if (modCount != expectedModCount) {
677              throw new ConcurrentModificationException();
678          }
679  
# Line 622 | Line 696 | public class ArrayList<E> extends Abstra
696          for (int i=0; i<size; i++)
697              a[i] = s.readObject();
698      }
699 +
700 +    /**
701 +     * Returns a list iterator over the elements in this list (in proper
702 +     * sequence), starting at the specified position in the list.
703 +     * The specified index indicates the first element that would be
704 +     * returned by an initial call to {@link ListIterator#next next}.
705 +     * An initial call to {@link ListIterator#previous previous} would
706 +     * return the element with the specified index minus one.
707 +     *
708 +     * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
709 +     *
710 +     * @throws IndexOutOfBoundsException {@inheritDoc}
711 +     */
712 +    public ListIterator<E> listIterator(int index) {
713 +        if (index < 0 || index > size)
714 +            throw new IndexOutOfBoundsException("Index: "+index);
715 +        return new ListItr(index);
716 +    }
717 +
718 +    /**
719 +     * Returns a list iterator over the elements in this list (in proper
720 +     * sequence).
721 +     *
722 +     * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
723 +     *
724 +     * @see #listIterator(int)
725 +     */
726 +    public ListIterator<E> listIterator() {
727 +        return new ListItr(0);
728 +    }
729 +
730 +    /**
731 +     * Returns an iterator over the elements in this list in proper sequence.
732 +     *
733 +     * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
734 +     *
735 +     * @return an iterator over the elements in this list in proper sequence
736 +     */
737 +    public Iterator<E> iterator() {
738 +        return new Itr();
739 +    }
740 +
741 +    /**
742 +     * An optimized version of AbstractList.Itr
743 +     */
744 +    private class Itr implements Iterator<E> {
745 +        int cursor;       // index of next element to return
746 +        int lastRet = -1; // index of last element returned; -1 if no such
747 +        int expectedModCount = modCount;
748 +
749 +        public boolean hasNext() {
750 +            return cursor != size;
751 +        }
752 +
753 +        @SuppressWarnings("unchecked")
754 +        public E next() {
755 +            checkForComodification();
756 +            int i = cursor;
757 +            if (i >= size)
758 +                throw new NoSuchElementException();
759 +            Object[] elementData = ArrayList.this.elementData;
760 +            if (i >= elementData.length)
761 +                throw new ConcurrentModificationException();
762 +            cursor = i + 1;
763 +            return (E) elementData[lastRet = i];
764 +        }
765 +
766 +        public void remove() {
767 +            if (lastRet < 0)
768 +                throw new IllegalStateException();
769 +            checkForComodification();
770 +
771 +            try {
772 +                ArrayList.this.remove(lastRet);
773 +                cursor = lastRet;
774 +                lastRet = -1;
775 +                expectedModCount = modCount;
776 +            } catch (IndexOutOfBoundsException ex) {
777 +                throw new ConcurrentModificationException();
778 +            }
779 +        }
780 +
781 +        final void checkForComodification() {
782 +            if (modCount != expectedModCount)
783 +                throw new ConcurrentModificationException();
784 +        }
785 +    }
786 +
787 +    /**
788 +     * An optimized version of AbstractList.ListItr
789 +     */
790 +    private class ListItr extends Itr implements ListIterator<E> {
791 +        ListItr(int index) {
792 +            super();
793 +            cursor = index;
794 +        }
795 +
796 +        public boolean hasPrevious() {
797 +            return cursor != 0;
798 +        }
799 +
800 +        public int nextIndex() {
801 +            return cursor;
802 +        }
803 +
804 +        public int previousIndex() {
805 +            return cursor - 1;
806 +        }
807 +
808 +        @SuppressWarnings("unchecked")
809 +        public E previous() {
810 +            checkForComodification();
811 +            int i = cursor - 1;
812 +            if (i < 0)
813 +                throw new NoSuchElementException();
814 +            Object[] elementData = ArrayList.this.elementData;
815 +            if (i >= elementData.length)
816 +                throw new ConcurrentModificationException();
817 +            cursor = i;
818 +            return (E) elementData[lastRet = i];
819 +        }
820 +
821 +        public void set(E e) {
822 +            if (lastRet < 0)
823 +                throw new IllegalStateException();
824 +            checkForComodification();
825 +
826 +            try {
827 +                ArrayList.this.set(lastRet, e);
828 +            } catch (IndexOutOfBoundsException ex) {
829 +                throw new ConcurrentModificationException();
830 +            }
831 +        }
832 +
833 +        public void add(E e) {
834 +            checkForComodification();
835 +
836 +            try {
837 +                int i = cursor;
838 +                ArrayList.this.add(i, e);
839 +                cursor = i + 1;
840 +                lastRet = -1;
841 +                expectedModCount = modCount;
842 +            } catch (IndexOutOfBoundsException ex) {
843 +                throw new ConcurrentModificationException();
844 +            }
845 +        }
846 +    }
847 +
848 +    /**
849 +     * Returns a view of the portion of this list between the specified
850 +     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.  (If
851 +     * {@code fromIndex} and {@code toIndex} are equal, the returned list is
852 +     * empty.)  The returned list is backed by this list, so non-structural
853 +     * changes in the returned list are reflected in this list, and vice-versa.
854 +     * The returned list supports all of the optional list operations.
855 +     *
856 +     * <p>This method eliminates the need for explicit range operations (of
857 +     * the sort that commonly exist for arrays).  Any operation that expects
858 +     * a list can be used as a range operation by passing a subList view
859 +     * instead of a whole list.  For example, the following idiom
860 +     * removes a range of elements from a list:
861 +     * <pre>
862 +     *      list.subList(from, to).clear();
863 +     * </pre>
864 +     * Similar idioms may be constructed for {@link #indexOf(Object)} and
865 +     * {@link #lastIndexOf(Object)}, and all of the algorithms in the
866 +     * {@link Collections} class can be applied to a subList.
867 +     *
868 +     * <p>The semantics of the list returned by this method become undefined if
869 +     * the backing list (i.e., this list) is <i>structurally modified</i> in
870 +     * any way other than via the returned list.  (Structural modifications are
871 +     * those that change the size of this list, or otherwise perturb it in such
872 +     * a fashion that iterations in progress may yield incorrect results.)
873 +     *
874 +     * @throws IndexOutOfBoundsException {@inheritDoc}
875 +     * @throws IllegalArgumentException {@inheritDoc}
876 +     */
877 +    public List<E> subList(int fromIndex, int toIndex) {
878 +        subListRangeCheck(fromIndex, toIndex, size);
879 +        return new SubList(this, 0, fromIndex, toIndex);
880 +    }
881 +
882 +    static void subListRangeCheck(int fromIndex, int toIndex, int size) {
883 +        if (fromIndex < 0)
884 +            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
885 +        if (toIndex > size)
886 +            throw new IndexOutOfBoundsException("toIndex = " + toIndex);
887 +        if (fromIndex > toIndex)
888 +            throw new IllegalArgumentException("fromIndex(" + fromIndex +
889 +                                               ") > toIndex(" + toIndex + ")");
890 +    }
891 +
892 +    private class SubList extends AbstractList<E> implements RandomAccess {
893 +        private final AbstractList<E> parent;
894 +        private final int parentOffset;
895 +        private final int offset;
896 +        private int size;
897 +
898 +        SubList(AbstractList<E> parent,
899 +                int offset, int fromIndex, int toIndex) {
900 +            this.parent = parent;
901 +            this.parentOffset = fromIndex;
902 +            this.offset = offset + fromIndex;
903 +            this.size = toIndex - fromIndex;
904 +            this.modCount = ArrayList.this.modCount;
905 +        }
906 +
907 +        public E set(int index, E e) {
908 +            rangeCheck(index);
909 +            checkForComodification();
910 +            E oldValue = ArrayList.this.elementData(offset + index);
911 +            ArrayList.this.elementData[offset + index] = e;
912 +            return oldValue;
913 +        }
914 +
915 +        public E get(int index) {
916 +            rangeCheck(index);
917 +            checkForComodification();
918 +            return ArrayList.this.elementData(offset + index);
919 +        }
920 +
921 +        public int size() {
922 +            checkForComodification();
923 +            return this.size;
924 +        }
925 +
926 +        public void add(int index, E e) {
927 +            rangeCheckForAdd(index);
928 +            checkForComodification();
929 +            parent.add(parentOffset + index, e);
930 +            this.modCount = parent.modCount;
931 +            this.size++;
932 +        }
933 +
934 +        public E remove(int index) {
935 +            rangeCheck(index);
936 +            checkForComodification();
937 +            E result = parent.remove(parentOffset + index);
938 +            this.modCount = parent.modCount;
939 +            this.size--;
940 +            return result;
941 +        }
942 +
943 +        protected void removeRange(int fromIndex, int toIndex) {
944 +            checkForComodification();
945 +            parent.removeRange(parentOffset + fromIndex,
946 +                               parentOffset + toIndex);
947 +            this.modCount = parent.modCount;
948 +            this.size -= toIndex - fromIndex;
949 +        }
950 +
951 +        public boolean addAll(Collection<? extends E> c) {
952 +            return addAll(this.size, c);
953 +        }
954 +
955 +        public boolean addAll(int index, Collection<? extends E> c) {
956 +            rangeCheckForAdd(index);
957 +            int cSize = c.size();
958 +            if (cSize==0)
959 +                return false;
960 +
961 +            checkForComodification();
962 +            parent.addAll(parentOffset + index, c);
963 +            this.modCount = parent.modCount;
964 +            this.size += cSize;
965 +            return true;
966 +        }
967 +
968 +        public Iterator<E> iterator() {
969 +            return listIterator();
970 +        }
971 +
972 +        public ListIterator<E> listIterator(final int index) {
973 +            checkForComodification();
974 +            rangeCheckForAdd(index);
975 +
976 +            return new ListIterator<E>() {
977 +                int cursor = index;
978 +                int lastRet = -1;
979 +                int expectedModCount = ArrayList.this.modCount;
980 +
981 +                public boolean hasNext() {
982 +                    return cursor != SubList.this.size;
983 +                }
984 +
985 +                @SuppressWarnings("unchecked")
986 +                public E next() {
987 +                    checkForComodification();
988 +                    int i = cursor;
989 +                    if (i >= SubList.this.size)
990 +                        throw new NoSuchElementException();
991 +                    Object[] elementData = ArrayList.this.elementData;
992 +                    if (offset + i >= elementData.length)
993 +                        throw new ConcurrentModificationException();
994 +                    cursor = i + 1;
995 +                    return (E) elementData[offset + (lastRet = i)];
996 +                }
997 +
998 +                public boolean hasPrevious() {
999 +                    return cursor != 0;
1000 +                }
1001 +
1002 +                @SuppressWarnings("unchecked")
1003 +                public E previous() {
1004 +                    checkForComodification();
1005 +                    int i = cursor - 1;
1006 +                    if (i < 0)
1007 +                        throw new NoSuchElementException();
1008 +                    Object[] elementData = ArrayList.this.elementData;
1009 +                    if (offset + i >= elementData.length)
1010 +                        throw new ConcurrentModificationException();
1011 +                    cursor = i;
1012 +                    return (E) elementData[offset + (lastRet = i)];
1013 +                }
1014 +
1015 +                public int nextIndex() {
1016 +                    return cursor;
1017 +                }
1018 +
1019 +                public int previousIndex() {
1020 +                    return cursor - 1;
1021 +                }
1022 +
1023 +                public void remove() {
1024 +                    if (lastRet < 0)
1025 +                        throw new IllegalStateException();
1026 +                    checkForComodification();
1027 +
1028 +                    try {
1029 +                        SubList.this.remove(lastRet);
1030 +                        cursor = lastRet;
1031 +                        lastRet = -1;
1032 +                        expectedModCount = ArrayList.this.modCount;
1033 +                    } catch (IndexOutOfBoundsException ex) {
1034 +                        throw new ConcurrentModificationException();
1035 +                    }
1036 +                }
1037 +
1038 +                public void set(E e) {
1039 +                    if (lastRet < 0)
1040 +                        throw new IllegalStateException();
1041 +                    checkForComodification();
1042 +
1043 +                    try {
1044 +                        ArrayList.this.set(offset + lastRet, e);
1045 +                    } catch (IndexOutOfBoundsException ex) {
1046 +                        throw new ConcurrentModificationException();
1047 +                    }
1048 +                }
1049 +
1050 +                public void add(E e) {
1051 +                    checkForComodification();
1052 +
1053 +                    try {
1054 +                        int i = cursor;
1055 +                        SubList.this.add(i, e);
1056 +                        cursor = i + 1;
1057 +                        lastRet = -1;
1058 +                        expectedModCount = ArrayList.this.modCount;
1059 +                    } catch (IndexOutOfBoundsException ex) {
1060 +                        throw new ConcurrentModificationException();
1061 +                    }
1062 +                }
1063 +
1064 +                final void checkForComodification() {
1065 +                    if (expectedModCount != ArrayList.this.modCount)
1066 +                        throw new ConcurrentModificationException();
1067 +                }
1068 +            };
1069 +        }
1070 +
1071 +        public List<E> subList(int fromIndex, int toIndex) {
1072 +            subListRangeCheck(fromIndex, toIndex, size);
1073 +            return new SubList(this, offset, fromIndex, toIndex);
1074 +        }
1075 +
1076 +        private void rangeCheck(int index) {
1077 +            if (index < 0 || index >= this.size)
1078 +                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1079 +        }
1080 +
1081 +        private void rangeCheckForAdd(int index) {
1082 +            if (index < 0 || index > this.size)
1083 +                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1084 +        }
1085 +
1086 +        private String outOfBoundsMsg(int index) {
1087 +            return "Index: "+index+", Size: "+this.size;
1088 +        }
1089 +
1090 +        private void checkForComodification() {
1091 +            if (ArrayList.this.modCount != this.modCount)
1092 +                throw new ConcurrentModificationException();
1093 +        }
1094 +    }
1095   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines