.toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?

itsadok picture itsadok · Oct 6, 2008 · Viewed 80.2k times · Source

Assuming I have an ArrayList

ArrayList<MyClass> myList;

And I want to call toArray, is there a performance reason to use

MyClass[] arr = myList.toArray(new MyClass[myList.size()]);

over

MyClass[] arr = myList.toArray(new MyClass[0]);

?

I prefer the second style, since it's less verbose, and I assumed that the compiler will make sure the empty array doesn't really get created, but I've been wondering if that's true.

Of course, in 99% of the cases it doesn't make a difference one way or the other, but I'd like to keep a consistent style between my normal code and my optimized inner loops...

Answer

Georgi picture Georgi · Oct 6, 2008

As of ArrayList in Java 5, the array will be filled already if it has the right size (or is bigger). Consequently

MyClass[] arr = myList.toArray(new MyClass[myList.size()]);

will create one array object, fill it and return it to "arr". On the other hand

MyClass[] arr = myList.toArray(new MyClass[0]);

will create two arrays. The second one is an array of MyClass with length 0. So there is an object creation for an object that will be thrown away immediately. As far as the source code suggests the compiler / JIT cannot optimize this one so that it is not created. Additionally, using the zero-length object results in casting(s) within the toArray() - method.

See the source of ArrayList.toArray():

public <T> T[] toArray(T[] a) {
    if (a.length < size)
        // Make a new array of a's runtime type, but my contents:
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());
    System.arraycopy(elementData, 0, a, 0, size);
    if (a.length > size)
        a[size] = null;
    return a;
}

Use the first method so that only one object is created and avoid (implicit but nevertheless expensive) castings.