RFR(s): 8060192: Add default method Collection.toArray(generator)

Stuart Marks stuart.marks at oracle.com
Wed Dec 6 01:56:52 UTC 2017

> The signature of the proposed generator is
>> public <T> T[] toArray(IntFunction<T[]> generator)
> So I don't think that anything has really changed in this regard; T
> can still be unrelated to E.

Right, the new method doesn't offer any safety compared to toArray(T[]). You can 
still get ArrayStoreException if T is incompatible with E. That's in part what 
led me to update the @throws ArrayStoreException text, since the previous text 
was basically wrong. But fundamentally the problem is unchanged.

There's a related enhancement request

     add typesafe static Collections.toArray(Collection<? extends T>, 

that would provide static type safety for this operation. Unclear whether it's 
worthwhile to add something like this, though.

> That said, sending in a constant String[0] is probably just as good as
> a generator, or better (in my naive estimation the tradeoff is a >0
> comparison versus an interface method dispatch), than an i -> new
> String[i] unless some kind of benchmark would appear which disproves
> that hypothesis.

I did some quick benchmarking, and it looks like String[]::new is a shade faster 
(heh) than new String[size], but not quite as fast as new String[0]. But take 
these results with a grain of salt. I was doing the benchmarking on my laptop 
with my entire environment running, and I was also measuring my development 
fastdebug build. I wasn't able to see the same difference between new 
String[size] and new String[0] that Shipilëv observed.[1] It would be 
interesting to get some rigorous benchmarks to compare these, but I haven't yet 
taken the time to do this.

I don't think the main point of this is performance, though. I think the new 
preferred way to create an array of a particular type should be 
toArray(Foo[]::new), which is preferable to toArray(new Foo[0]) or 
toArray(EMPTY_FOO_ARRAY). I suppose those of us "in the know" would recognize 
toArray(new Foo[0]) to be idiomatic. But to understand it, you have to fully 
understand the semantics of toArray(T[]), and you have to have read Shipilëv's 
article to understand why creating an apparently wasted zero-sized array is 
(usually) the right thing. That seems pretty obscure.


[1] https://shipilev.net/blog/2016/arrays-wisdom-ancients/

More information about the core-libs-dev mailing list