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 <marti...@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.ma...@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




Reply via email to