Collection.toArray(IntFunction)

Paul Sandoz paul.sandoz at oracle.com
Thu May 30 01:34:03 PDT 2013


On May 30, 2013, at 9:30 AM, Peter Levart <peter.levart at gmail.com> wrote:

> Hi,
> 
> Are you still accepting suggestions for lambdafication of core libraries?
> 

Yes, but time is running out :-)


> What about the following default method in j.u.Collection:
> 
>     /**
>      * Returns an array containing all of the elements in this collection;
>      * an array is constructed by invoking the given {@code arrayFactory}
>      * with the {@code int} argument of this {@code Collection)'s 
> {@link #size}.
>      * If the collection fits in the constructed array, it is returned 
> therein.
>      * Otherwise, a new array is allocated with the same runtime type 
> and the
>      * size of this collection.
>      *
>      * <p>If this collection fits in the array constructed by {@code 
> arrayFactory}
>      * with room to spare (i.e., the array has more elements than this 
> collection),
>      * the element in the array immediately following the end of the 
> collection is
>      * set to <tt>null</tt>.  (This is useful in determining the length 
> of this
>      * collection <i>only</i> if the caller knows that this collection does
>      * not contain any <tt>null</tt> elements.)
>      *
>      * <p>If this collection makes any guarantees as to what order its 
> elements
>      * are returned by its iterator, this method must return the 
> elements in
>      * the same order.
>      *
>      * <p>Like the {@link #toArray()} method, this method acts as 
> bridge between
>      * array-based and collection-based APIs.  Further, this method allows
>      * precise control over the runtime type of the output array, and may
>      * be used to save allocation costs.
>      *
>      * <p>Suppose <tt>x</tt> is a collection known to contain only strings.
>      * The following code can be used to dump the collection into a newly
>      * allocated array of <tt>String</tt>:
>      *
>      * <pre>
>      *     String[] y = x.toArray(String[]::new);</pre>
>      *
>      * Note that <tt>x.toArray(String[]::new)</tt> is identical in 
> function to
>      * <tt>x.toArray(new String[x.size()])</tt>, except that in 
> situations where
>      * the reference to {@code Collection} is not already available as 
> a local variable
>      * (such as when it is returned from a call to a method) there's no 
> need to
>      * introduce such local variable.
>      *
>      * @param arrayFactory the array factory function that will be 
> invoked to
>      *        construct the array of appropriate size into which the 
> elements of
>      *        this collection are to be stored.
>      * @return an array containing all of the elements in this collection
>      * @throws ArrayStoreException if the component type of the array 
> constructed
>      *         by {@code arrayFactory} is not a supertype of the 
> runtime type of
>      *         every element in this collection
>      * @throws NullPointerException if the specified arrayFactory is 
> null or if
>      *         arrayFactory returns null array.
>      * @since 1.8
>      */
>     default <T> T[] toArray(IntFunction<T[]> arrayFactory) {
>         return toArray(arrayFactory.apply(size()));
>     }
> 

This was previously discussed in the lambda EG. It was definitely recognised that the current Collection.toArray methods "stink" and we did not want to propagate the smell to Stream. We got to the point of sorting this out on Stream and suggested after that it may be worth propagating back to Collection but i think it got lost in the noise of other stuff. I will raise this with the EG.


> I also noticed an error in the javadoc of the other 
> Collection.toArray(T[]) method (line 240). Instead of the following:
> 
>      * @throws ArrayStoreException if the *runtime*type of the 
> specified array
>      *         is not a supertype of the runtime type of every element in
>      *         this collection
> 
> I think it should be:
> 
>      * @throws ArrayStoreException if the *component*type of the 
> specified array
>      *         is not a supertype of the runtime type of every element in
>      *         this collection
> 
> 

Bug logged.

Thanks,
Paul.


More information about the lambda-dev mailing list