RFR(s): 8060192: Add default method Collection.toArray(generator)
Peter Levart
peter.levart at gmail.com
Sun Jun 17 08:50:58 UTC 2018
Hi Stuart,
On 06/15/18 03:02, Stuart Marks wrote:
> Comparing this to the type token alternatives, for simple tasks like
> converting Collection<String> to String[], things are about equal:
>
> toArray(String[]::new)
> toArray(String.class)
> toArray(String[].class)
>
> However, things are hairier if the element type of the collection is
> generic, such as Collection<List<String>>. The result type is a
> generic array List<String>[]. Using class literals or array
> constructor references will necessitate using an unchecked cast,
> because none of these can be used to represent a generic type.
>
> However, it's possible to use a method reference to provide a properly
> generic IntFunction. This would enable the toArray(generator) method
> to be used without any unchecked casts. (The method it refers to might
> need have an unchecked cast within it, though.) Such a method could
> also be reused for the corresponding Stream.toArray(generator) method.
>
> For these reasons I'd like to proceed with adding toArray(generator) API.
It's a little strange that the generator function is used to construct
an empty array (at least in the default method, but overrides will
likely do the same if they want to avoid pre-zeroing overhead) in order
to just extract the array's type from it. Someone could reasonably
expect the provided function to be called with the exact length of
needed array. The Collection.toArray(T[]) at least gives user an option
to actually fully use the provided array, if user provides the correct
length. The argument about using (and re-using) a method so that a
method reference can be passed to the method without any unchecked casts
is equally true for any of the 3 alternatives shown - the method itself
might need unchecked casts, but its usage not:
static List<String>[] array(int len)
static Class<List<String>> elementType()
static Class<List<String>[]> arrayType()
But I can see that you want to align the API with Stream.toArray, while
still providing the optimal implementation. It's just that the API
doesn't fit the usecase. The function approach makes more sense in the
Stream API where it is explicitly explained that it may be used to
construct arrays needed to hold intermediary results of partitioned
parallel execution too, but in Collection API it is usually the case to
just provide a copy of the underlying data structure in the most optimal
way (without pre-zeroing overhead) and for that purpose, 2nd and 3rd
alternatives are a better fit.
Suppose Stream took a different approach and used the 2nd or 3rd
approach (which is universal). Would then Collection API also get the
same method?
Regards, Peter
More information about the core-libs-dev
mailing list