--- jsr166/src/main/java/util/ArrayList.java 2005/11/25 13:27:05 1.1 +++ jsr166/src/main/java/util/ArrayList.java 2005/11/26 04:33:04 1.5 @@ -101,9 +101,9 @@ public class ArrayList extends Abstra /** * Constructs an empty list with the specified initial capacity. * - * @param initialCapacity the initial capacity of the list - * @exception IllegalArgumentException if the specified initial capacity - * is negative + * @param initialCapacity the initial capacity of the list + * @throws IllegalArgumentException if the specified initial capacity + * is negative */ public ArrayList(int initialCapacity) { super(); @@ -123,20 +123,40 @@ public class ArrayList extends Abstra /** * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection's - * iterator. + * iterator. The ArrayList instance has an initial capacity of + * 110% the size of the specified collection. * * @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) { - Object[] a = c.toArray(); - // If c.toArray incorrectly doesn't return Object[], copy it. - if (a.getClass() != Object[].class) - a = Arrays.copyOf(a, a.length, Object[].class); - elementData = a; - size = a.length; + int size = c.size(); + // 10% for growth + int cap = ((size/10)+1)*11; + if (cap > 0) { + Object[] a = new Object[cap]; + a[size] = a[size+1] = UNALLOCATED; + Object[] b = c.toArray(a); + if (b[size] == null && b[size+1] == UNALLOCATED) { + b[size+1] = null; + elementData = b; + this.size = size; + return; + } + } + initFromConcurrentlyMutating(c); + } + + private void initFromConcurrentlyMutating(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); } + private final static Object UNALLOCATED = new Object(); + /** * Trims the capacity of this ArrayList instance to be the * list's current size. An application can use this operation to minimize @@ -155,14 +175,7 @@ public class ArrayList extends Abstra * 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 - */ - /** - * 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 + * @param minCapacity the desired minimum capacity */ public void ensureCapacity(int minCapacity) { modCount++; @@ -171,13 +184,14 @@ public class ArrayList extends Abstra } /** - * Increase the capacity of the array. - * @param minCapacity the desired minimum capacity + * Increases the capacity of the array. + * + * @param minCapacity the desired minimum capacity */ private void growArray(int minCapacity) { int oldCapacity = elementData.length; // Double size if small; else grow by 50% - int newCapacity = ((oldCapacity < 64)? + int newCapacity = ((oldCapacity < 64)? (oldCapacity * 2): ((oldCapacity * 3)/2 + 1)); if (newCapacity < minCapacity) @@ -328,15 +342,13 @@ public class ArrayList extends Abstra // Positional Access Operations - /** - * Create and return an appropriate exception for indexing errors + /** + * Create and return an appropriate exception for indexing errors */ private static IndexOutOfBoundsException rangeException(int i, int s) { return new IndexOutOfBoundsException("Index: " + i + ", Size: " + s); } - // Positional Access Operations - /** * Returns the element at the specified position in this list. * @@ -423,7 +435,7 @@ public class ArrayList extends Abstra Object oldValue = elementData[index]; int numMoved = s - index; if (numMoved > 0) - System.arraycopy(elementData, index+1, elementData, index, + System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[s] = null; // forget removed element return (E)oldValue; @@ -639,7 +651,7 @@ public class ArrayList extends Abstra throw new IndexOutOfBoundsException("Index: "+index); return new ArrayListIterator(index); } - + /** * Returns an iterator over the elements in this list in proper sequence. * @@ -650,7 +662,7 @@ public class ArrayList extends Abstra } /** - * A streamlined version of AbstractList.Itr + * A streamlined version of AbstractList.Itr */ final class ArrayListIterator implements ListIterator { int cursor; // index of next element to return; @@ -688,7 +700,7 @@ public class ArrayList extends Abstra lastRet = i; cursor = i + 1; return e; - } catch (IndexOutOfBoundsException fallthrough) { + } catch (IndexOutOfBoundsException fallthrough) { } } } @@ -707,7 +719,7 @@ public class ArrayList extends Abstra lastRet = i; cursor = i; return e; - } catch (IndexOutOfBoundsException fallthrough) { + } catch (IndexOutOfBoundsException fallthrough) { } } } @@ -719,7 +731,7 @@ public class ArrayList extends Abstra public void remove() { if (lastRet < 0) throw new IllegalStateException(); - if (modCount != expectedModCount) + if (modCount != expectedModCount) throw new ConcurrentModificationException(); ArrayList.this.remove(lastRet); if (lastRet < cursor) @@ -731,14 +743,14 @@ public class ArrayList extends Abstra public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); - if (modCount != expectedModCount) + if (modCount != expectedModCount) throw new ConcurrentModificationException(); ArrayList.this.set(lastRet, e); expectedModCount = modCount; } public void add(E e) { - if (modCount != expectedModCount) + if (modCount != expectedModCount) throw new ConcurrentModificationException(); ArrayList.this.add(cursor++, e); lastRet = -1;