Index: classlib/modules/luni/src/main/java/java/util/AbstractCollection.java =================================================================== --- classlib/modules/luni/src/main/java/java/util/AbstractCollection.java (revision 1036329) +++ classlib/modules/luni/src/main/java/java/util/AbstractCollection.java (working copy) @@ -53,7 +53,7 @@ * If the passed {@code Collection} is changed during the process of adding elements * to this {@code Collection}, the behavior depends on the behavior of the passed * {@code Collection}. - * + * * @param collection * the collection of objects. * @return {@code true} if this {@code Collection} is modified, {@code false} @@ -89,7 +89,7 @@ *

* Concrete implementations usually can clear a {@code Collection} more efficiently * and should therefore overwrite this method. - * + * * @throws UnsupportedOperationException * it the iterator does not support removing elements from * this {@code Collection} @@ -113,7 +113,7 @@ * the iterator until the element is found. If {@code object == null} then * each element {@code e} returned by the iterator is compared with the test * {@code e == null}. - * + * * @param object * the object to search for. * @return {@code true} if object is an element of this {@code Collection}, {@code @@ -147,7 +147,7 @@ * specified {@code Collection}. This implementation iterates over the specified * {@code Collection}. If one element returned by the iterator is not contained in * this {@code Collection}, then {@code false} is returned; {@code true} otherwise. - * + * * @param collection * the collection of objects. * @return {@code true} if all objects in the specified {@code Collection} are @@ -175,7 +175,7 @@ /** * Returns if this {@code Collection} contains no elements. This implementation * tests, whether {@code size} returns 0. - * + * * @return {@code true} if this {@code Collection} has no elements, {@code false} * otherwise. * @@ -193,7 +193,7 @@ *

* In this class this method is declared abstract and has to be implemented * by concrete {@code Collection} implementations. - * + * * @return an iterator for accessing the {@code Collection} contents. */ public abstract Iterator iterator(); @@ -209,7 +209,7 @@ * {@code true} is returned, {@code false} otherwise. If the iterator does * not support removing elements, an {@code UnsupportedOperationException} * is thrown. - * + * * @param object * the object to remove. * @return {@code true} if this {@code Collection} is modified, {@code false} @@ -254,7 +254,7 @@ * remove} method is called on the iterator. If the iterator does not * support removing elements, an {@code UnsupportedOperationException} is * thrown. - * + * * @param collection * the collection of objects to remove. * @return {@code true} if this {@code Collection} is modified, {@code false} @@ -295,7 +295,7 @@ * remove} method is called on the iterator. If the iterator does not * support removing elements, an {@code UnsupportedOperationException} is * thrown. - * + * * @param collection * the collection of objects to retain. * @return {@code true} if this {@code Collection} is modified, {@code false} @@ -329,7 +329,7 @@ *

* In this class this method is declared abstract and has to be implemented * by concrete {@code Collection} implementations. - * + * * @return how many objects this {@code Collection} contains, or {@code Integer.MAX_VALUE} * if there are more than {@code Integer.MAX_VALUE} elements in this * {@code Collection}. @@ -337,28 +337,57 @@ public abstract int size(); public Object[] toArray() { - int size = size(), index = 0; - Iterator it = iterator(); - Object[] array = new Object[size]; - while (index < size) { - array[index++] = it.next(); + int index = 0, size = size(); + Iterator iterator = iterator(); + Object[] toArray = new Object[size]; + while (iterator.hasNext()) { + if (index == toArray.length) { + toArray = trimOrAppend(toArray, toArray.length * 2 + 1); + } + for (; index < toArray.length; index++) { + if (!iterator.hasNext()) { + return trimOrAppend(toArray, index); + } + toArray[index] = iterator.next(); + } } - return array; + return trimOrAppend(toArray, index); } + private Object[] trimOrAppend(Object[] toArray, int newLength) { + if (newLength == toArray.length) { + return toArray; + } + int copyLength = newLength < toArray.length ? newLength + : toArray.length; + Object[] newArray = new Object[newLength]; + System.arraycopy(toArray, 0, newArray, 0, copyLength); + return newArray; + } + + @SuppressWarnings("unchecked") public T[] toArray(T[] contents) { int size = size(), index = 0; + Class ct = contents.getClass().getComponentType(); if (size > contents.length) { - Class ct = contents.getClass().getComponentType(); contents = (T[]) Array.newInstance(ct, size); } - for (E entry : this) { - contents[index++] = (T) entry; - } - if (index < contents.length) { + Object[] toArray = toArray(); + if (toArray.length < contents.length) { + for (Object entry: toArray) { + contents[index++] = (T) entry; + } contents[index] = null; } + else { + //Resize the contents Array to fit the Collection elements + contents = (T[]) Array.newInstance(ct, toArray.length); + for (Object entry: toArray) { + contents[index++] = (T) entry; + } + } + return contents; } @@ -366,7 +395,7 @@ * Returns the string representation of this {@code Collection}. The presentation * has a specific format. It is enclosed by square brackets ("[]"). Elements * are separated by ', ' (comma and space). - * + * * @return the string representation of this {@code Collection}. */ @Override