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.15 by jsr166, Mon Dec 12 00:04:16 2005 UTC vs.
Revision 1.21 by jsr166, Sun May 28 23:36:29 2006 UTC

# Line 6 | Line 6
6   */
7  
8   package java.util;
9 import java.util.*; // for javadoc (till 6280605 is fixed)
9  
10   /**
11   * Resizable-array implementation of the <tt>List</tt> interface.  Implements
# Line 67 | Line 66 | import java.util.*; // for javadoc (till
66   * should be used only to detect bugs.</i><p>
67   *
68   * This class is a member of the
69 < * <a href="{@docRoot}/../guide/collections/index.html">
69 > * <a href="{@docRoot}/../technotes/guides/collections/index.html">
70   * Java Collections Framework</a>.
71   *
72   * @author  Josh Bloch
# Line 123 | Line 122 | public class ArrayList<E> extends Abstra
122      /**
123       * Constructs a list containing the elements of the specified
124       * collection, in the order they are returned by the collection's
125 <     * iterator.  The <tt>ArrayList</tt> instance has an initial capacity of
127 <     * 110% the size of the specified collection.
125 >     * iterator.
126       *
127       * @param c the collection whose elements are to be placed into this list
128       * @throws NullPointerException if the specified collection is null
129       */
130      public ArrayList(Collection<? extends E> c) {
131 <        int size = c.size();
132 <        // 10% for growth
133 <        int cap = ((size/10)+1)*11;
134 <        if (cap > 0) {
135 <            Object[] a = new Object[cap];
138 <            a[size] = a[size+1] = UNALLOCATED;
139 <            Object[] b = c.toArray(a);
140 <            if (b[size] == null && b[size+1] == UNALLOCATED) {
141 <                b[size+1] = null;
142 <                elementData = b;
143 <                this.size = size;
144 <                return;
145 <            }
146 <        }
147 <        initFromConcurrentlyMutating(c);
131 >        elementData = c.toArray();
132 >        size = elementData.length;
133 >        // c.toArray might (incorrectly) not return Object[] (see 6260652)
134 >        if (elementData.getClass() != Object[].class)
135 >            elementData = Arrays.copyOf(elementData, size, Object[].class);
136      }
137  
138      private void initFromConcurrentlyMutating(Collection<? extends E> c) {
# Line 189 | Line 177 | public class ArrayList<E> extends Abstra
177       * @param minCapacity the desired minimum capacity
178       */
179      private void growArray(int minCapacity) {
180 <        if (minCapacity < 0) // overflow
181 <            throw new OutOfMemoryError();
180 >        if (minCapacity < 0) // overflow
181 >            throw new OutOfMemoryError();
182          int oldCapacity = elementData.length;
183          // Double size if small; else grow by 50%
184 <        int newCapacity = ((oldCapacity < 64)?
185 <                           ((oldCapacity + 1) * 2):
184 >        int newCapacity = ((oldCapacity < 64) ?
185 >                           ((oldCapacity + 1) * 2) :
186                             ((oldCapacity / 2) * 3));
187          if (newCapacity < 0) // overflow
188              newCapacity = Integer.MAX_VALUE;
# Line 347 | Line 335 | public class ArrayList<E> extends Abstra
335      // Positional Access Operations
336  
337      /**
338 <     * Returns error message string for IndexOutOfBoundsExceptions
338 >     * Throws an appropriate exception for indexing errors.
339       */
340 <    private String ioobe(int index) {
341 <        return "Index: " + index + ", Size: " + size;
340 >    private static void indexOutOfBounds(int i, int s) {
341 >        throw new IndexOutOfBoundsException("Index: " + i + ", Size: " + s);
342      }
343  
344      /**
# Line 362 | Line 350 | public class ArrayList<E> extends Abstra
350       */
351      public E get(int index) {
352          if (index >= size)
353 <            throw new IndexOutOfBoundsException(ioobe(index));
354 <        return (E)elementData[index];
353 >            indexOutOfBounds(index, size);
354 >        return (E) elementData[index];
355      }
356  
357      /**
# Line 377 | Line 365 | public class ArrayList<E> extends Abstra
365       */
366      public E set(int index, E element) {
367          if (index >= size)
368 <            throw new IndexOutOfBoundsException(ioobe(index));
381 <
368 >            indexOutOfBounds(index, size);
369          E oldValue = (E) elementData[index];
370          elementData[index] = element;
371          return oldValue;
# Line 396 | Line 383 | public class ArrayList<E> extends Abstra
383          if (s >= elementData.length)
384              growArray(s + 1);
385          elementData[s] = e;
386 <        size = s + 1;
387 <        return true;
386 >        size = s + 1;
387 >        return true;
388      }
389  
390      /**
# Line 412 | Line 399 | public class ArrayList<E> extends Abstra
399      public void add(int index, E element) {
400          int s = size;
401          if (index > s || index < 0)
402 <            throw new IndexOutOfBoundsException(ioobe(index));
402 >            indexOutOfBounds(index, s);
403          modCount++;
404          if (s >= elementData.length)
405              growArray(s + 1);
406          System.arraycopy(elementData, index,
407 <                         elementData, index + 1, s - index);
407 >                         elementData, index + 1, s - index);
408          elementData[index] = element;
409          size = s + 1;
410      }
# Line 434 | Line 421 | public class ArrayList<E> extends Abstra
421      public E remove(int index) {
422          int s = size - 1;
423          if (index > s)
424 <            throw new IndexOutOfBoundsException(ioobe(index));
424 >            indexOutOfBounds(index, size);
425          modCount++;
426 <        E oldValue = (E)elementData[index];
426 >        E oldValue = (E) elementData[index];
427          int numMoved = s - index;
428          if (numMoved > 0)
429              System.arraycopy(elementData, index + 1,
430 <                             elementData, index, numMoved);
430 >                             elementData, index, numMoved);
431          elementData[s] = null;
432 <        size = s;
432 >        size = s;
433          return oldValue;
434      }
435  
# Line 542 | Line 529 | public class ArrayList<E> extends Abstra
529       */
530      public boolean addAll(int index, Collection<? extends E> c) {
531          if (index > size || index < 0)
532 <            throw new IndexOutOfBoundsException(ioobe(index));
532 >            indexOutOfBounds(index, size);
533  
534          Object[] a = c.toArray();
535          int numNew = a.length;
# Line 627 | Line 614 | public class ArrayList<E> extends Abstra
614          for (int i=0; i<size; i++)
615              a[i] = s.readObject();
616      }
630
631
632    /**
633     * Returns a list-iterator of the elements in this list (in proper
634     * sequence), starting at the specified position in the list.
635     * Obeys the general contract of <tt>List.listIterator(int)</tt>.<p>
636     *
637     * The list-iterator is <i>fail-fast</i>: if the list is structurally
638     * modified at any time after the Iterator is created, in any way except
639     * through the list-iterator's own <tt>remove</tt> or <tt>add</tt>
640     * methods, the list-iterator will throw a
641     * <tt>ConcurrentModificationException</tt>.  Thus, in the face of
642     * concurrent modification, the iterator fails quickly and cleanly, rather
643     * than risking arbitrary, non-deterministic behavior at an undetermined
644     * time in the future.
645     *
646     * @param index index of the first element to be returned from the
647     *              list-iterator (by a call to <tt>next</tt>)
648     * @return a ListIterator of the elements in this list (in proper
649     *         sequence), starting at the specified position in the list
650     * @throws IndexOutOfBoundsException {@inheritDoc}
651     * @see List#listIterator(int)
652     */
653    public ListIterator<E> listIterator(int index) {
654        if (index < 0 || index > size)
655            throw new IndexOutOfBoundsException(ioobe(index));
656        return new ArrayListIterator(index);
657    }
658
659    /**
660     * {@inheritDoc}
661     */
662    public ListIterator<E> listIterator() {
663        return new ArrayListIterator(0);
664    }
665
666    /**
667     * Returns an iterator over the elements in this list in proper sequence.
668     *
669     * @return an iterator over the elements in this list in proper sequence
670     */
671    public Iterator<E> iterator() {
672        return new ArrayListIterator(0);
673    }
674
675    /**
676     * A streamlined version of AbstractList.ListItr
677     */
678    final class ArrayListIterator implements ListIterator<E> {
679        int cursor;           // index of next element to return;
680        int lastRet;          // index of last element, or -1 if no such
681        int expectedModCount; // to check for CME
682
683        ArrayListIterator(int index) {
684            cursor = index;
685            lastRet = -1;
686            expectedModCount = modCount;
687        }
688
689        public boolean hasNext() {
690            return cursor != size;
691        }
692
693        public boolean hasPrevious() {
694            return cursor != 0;
695        }
696
697        public int nextIndex() {
698            return cursor;
699        }
700
701        public int previousIndex() {
702            return cursor - 1;
703        }
704
705        public E next() {
706            try {
707                int i = cursor;
708                E next = get(i);
709                lastRet = i;
710                cursor = i + 1;
711                return next;
712            } catch (IndexOutOfBoundsException ex) {
713                throw new NoSuchElementException();
714            } finally {
715                if (expectedModCount != modCount)
716                    throw new ConcurrentModificationException();
717            }
718        }
719
720        public E previous() {
721            try {
722                int i = cursor - 1;
723                E prev = get(i);
724                lastRet = i;
725                cursor = i;
726                return prev;
727            } catch (IndexOutOfBoundsException ex) {
728                throw new NoSuchElementException();
729            } finally {
730                if (expectedModCount != modCount)
731                    throw new ConcurrentModificationException();
732            }
733        }
734
735        public void remove() {
736            if (lastRet < 0)
737                throw new IllegalStateException();
738            if (expectedModCount != modCount)
739                throw new ConcurrentModificationException();
740            ArrayList.this.remove(lastRet);
741            if (lastRet < cursor)
742                cursor--;
743            lastRet = -1;
744            expectedModCount = modCount;
745        }
746
747        public void set(E e) {
748            if (lastRet < 0)
749                throw new IllegalStateException();
750            if (expectedModCount != modCount)
751                throw new ConcurrentModificationException();
752            ArrayList.this.set(lastRet, e);
753            expectedModCount = modCount;
754        }
755
756        public void add(E e) {
757            if (expectedModCount != modCount)
758                throw new ConcurrentModificationException();
759            try {
760                ArrayList.this.add(cursor++, e);
761                lastRet = -1;
762                expectedModCount = modCount;
763            } catch (IndexOutOfBoundsException ex) {
764                throw new ConcurrentModificationException();
765            }
766        }
767    }
617   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines