ArrayFactory SAM type / toArray

Brian Goetz brian.goetz at oracle.com
Wed Sep 19 14:15:07 PDT 2012


> 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.

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

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.)

Josh writes:

> What problem are you trying solve?

I think the above should explain, but in a nutshell the problem is: the 
two existing precedents for toArray as done in Collection are both 
unfortunate, and I'd rather not propagate them blindly into Streams. 
They're probably the best we could have done without lambdas in the 
language, but with lambdas, a better alternative arises -- let the 
library create the array with a factory provided by the caller.  I would 
like to offer a better version of toArray for Streams, and possibly 
consider retrofitting onto Collection.



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