ArrayFactory SAM type / toArray

Remi Forax forax at
Wed Sep 19 14:20:23 PDT 2012

On 09/19/2012 11:15 PM, Brian Goetz wrote:
>> Why passing a lambda that will be called in the body of the toArray ?
>> It's simpler to directly pass the array.
> No, that's what the existing unfortunate toArray(T[]) does. Things 
> that are wrong with it:
>  - If you get the size wrong, it has to reallocate.
>  - If it reallocates, it has to do it reflectively.
>  - It is inherently racy.
> To see the racy part, consider an implementation like 
> SynchronizedList.  If the user does:
>  Foo[] array = c.toArray(new Foo[c.size()]);
> where c is a synchronized list, we acquire the lock, compute the size, 
> release the lock, and pass the array into toArray, which will have to 
> allocate again (reflectively) if the size has changed.  Whereas an 
> implementation of toArray(ArrayFactory) can create the array once at 
> the proper size while ensuring no concurrent modifications.

ok, the API is slightly better for synchronized collections, I never use 
them, and you still need to protect the code against mutations when 
using concurrent collections.

> So, comparing the status quo toArray(T[]) with the proposed (low 
> quality) default version:
>  - Worst case is identical
>  - Best case is better in that allocation is not done reflectively

as David says, Hostspot as an optimization for that :)

> And a non-crappy overriden implementation can be better still 
> (eliminate races.)
> Arguably the proposed approach also provides a better separation of 
> concerns; having the client allocate the array for the library seems 
> questionable.  (Arguably it is even better from an API design 
> perspective to pass a class literal rather than a lambda, but that 
> gets us back into reflection.)

see above.


More information about the lambda-libs-spec-observers mailing list