If we consider the specification of Collection.toArray(T[])
:
[…] If the collection fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this collection.
However there are some issues that would prevent doing the same with streams:
- an implementation cannot know in advance whether a stream of unknown size will fit
- with parallel streams, splitting a stream (
Spliterator
) of known size (i.e. SIZED
) could lead to 2 spliterators of unknown size if the original spliterator is not also SUBSIZED
, so you wouldn’t know where to put the data after splitting
in both cases, an implementation would still have to create new arrays and finish by copying the data, defeating the purpose of the above requirement.
As in a lot of scenarios you are working with streams of unknown size (a simple filter()
or flatMap()
would remove that property), you will often fall into the above limitations.
Moreover, even for the known size case, people were often allocating a new array of the right size at the time of calling Collection.toArray(T[])
. This was actually counter-productive in more recent versions of the JVM, so it would be a bad thing to bring the same issue in the Stream API.
In the end, if we remove the requirement to fill the provided array, there does not seem to be much benefit left over the toArray(IntFunction<T[]>)
version.