RFR(s): 8060192: Add default method Collection.toArray(generator)
Peter Levart
peter.levart at gmail.com
Fri Dec 8 12:04:48 UTC 2017
On 12/08/2017 04:09 AM, David Lloyd wrote:
> Yes! It would be even better for the "toArray(Class)" case if
> Class<T> had a "getArrayClass()" method which returned the Class<T[]>,
> which would allow:
>
> return (T[]) Arrays.copyOf(elementData, size, componentType.getArrayClass());
>
> and similar for other array-backed collections. I never understood
> why that method doesn't exist; in fact, am I wrong in understanding
> that "Array.newInstance(clazz, 0).getClass()" is effectively the only
> way to do this today?
I think there is a reason for Arrays.copyOf() to take an array type, not
the component type. If it was taking component type, you could pass in
primitive types too with no compile-time type checking, since int.class
is of Class<Integer> static type. So why not the following:
public interface Collection<E> extends Iterable<E> {
@SuppressWarnings("unchecked")
default <T> T[] toArray(Class<T[]> arrayType) {
return toArray((T[])
Array.newInstance(arrayType.getComponentType(), size()));
}
ArrayList override could then simply be this:
@Override
public <T> T[] toArray(Class<T[]> arrayType) {
return Arrays.copyOf(elementData, size, arrayType);
}
Regards, Peter
>
> On Thu, Dec 7, 2017 at 7:03 PM, Martin Buchholz <martinrb at google.com> wrote:
>> (I'm still trying to love this new API)
>>
>> The changes to the jsr166 tck are fine.
>>
>> I'm not convinced that the new implementation for ArrayList is progress.
>> The current implementation of toArray(T[]) does
>>
>> // Make a new array of a's runtime type, but my contents:
>> return (T[]) Arrays.copyOf(elementData, size, a.getClass());
>>
>> which does not have to pay the cost of zeroing the array, so is potentially
>> faster. (depends on whether the VM provides cheap pre-zeroed memory?! what
>> does jmh say?)
>>
>> If we're not getting type safety and not getting significantly better
>> performance, all we have is a more natural API. But toArray(IntFunction)
>> also seems not very natural to me, and we'll have to live with the
>> toArray(new String[0]) wart forever anyways. (But is it really so bad?)
>> (Maybe toArray(Class<componentType>) is actually more natural?)
>>
>> On Thu, Dec 7, 2017 at 2:58 PM, Stuart Marks <stuart.marks at oracle.com>
>> wrote:
>>
>>> [Martin: please review changes to the JSR 166 TCK.]
>>>
>>> Another updated webrev for this changeset:
>>>
>>> http://cr.openjdk.java.net/~smarks/reviews/8060192/webrev.2/
>>>
>>> This includes an override of toArray(IntFunction) in the implementation of
>>> Arrays.asList(), as requested by Tagir Valeev.
>>>
>>> Overrides are also added for various wrapper classes in j.u.Collections.
>>> Turns out there's a test test/jdk/java/util/Collections/Wrappers.java
>>> that checks to ensure that the wrappers don't inherit any default methods.
>>> (This has been a source of bugs in the past.)
>>>
>>> Significantly, this webrev also includes changes to several tests in the
>>> JSR 166 TCK. The issue is that these tests have cases for null handling,
>>> where they call
>>>
>>> coll.toArray(null)
>>>
>>> to ensure that NPE is thrown. Given that this method is now overloaded:
>>>
>>> toArray(T[])
>>> toArray(IntFunction)
>>>
>>> passing null is now ambiguous and thus generates a compiler error. I've
>>> modified the tests to call toArray((Object[])null) which is a bit of a
>>> stopgap. I can't think of anything obviously better to do, though.
>>>
>>> s'marks
>>>
>
>
More information about the core-libs-dev
mailing list