The difference between these two approaches:
String[] array = iName.toArray(new String[iName.size()]); String[] array = iName.toArray(new String[0]);
very different if there is a chance that the original set ( iName in this case) can be changed at the same time. If concurrency is not possible, then the first line is preferred.
This is not strictly applied in your example, where is the original ArrayList collection, which is not thread safe. But if the original collection is a parallel collection, then the behavior of the parallel modification is significant. In this case, the first line has a race condition. The calling thread first gets the size; another thread can then add or remove an element by resizing it. But then the calling thread selects the array with the old size and passes it to toArray .
This does not result in an error. Cases are clearly defined if you carefully read the specification of Collection.toArray(T[]) . If the collection grew, a new array would be allocated for it, which would make the caller's array redundant. If the collection is reduced, the tail of the array will end with zero elements. This is not necessarily an error, but any code that consumes the resulting array must be prepared to handle zeros, which can be unpleasant.
Passing a zero-length array avoids these problems at the possible cost of allocating a useless zero-length array. (You can store the cached version, but it adds clutter.) If the collection is empty, a zero-length array is simply returned. However, if the collection has elements, the collection itself selects an array of the correct size and fills it. This avoids the race condition of the caller in an array of "wrong" size.
In the Java 8 Streams API, the Stream.toArray method avoids this problem by passing a call to the factory array. This allows the caller to specify the type, but allows the collection to specify the desired size. This has not yet been finalized until Collections . This applies to RFE JDK-8060192 .
source share