0

Why is it necessary to allocate an array that can hold the values of a collection and pass it to the toArray(T []) method of this collection? I know there is the toArray() method that doesn't need the preallocated array, but this method returns Object[] which is absolutely bad. Also i would like to avoid type casting.

Example:

Set<String> strings = new HashSet<>();
// put some values in it
String[] stringArr = strings.toArray(/* preallocated array, why? */);

Assuming i use generics (everything else would be bad practice anyway), the used collection class should have enough information by itself to do this job for me. It could do something like this:

public someCollection<T> {
...
    public T[] toArray() {
        T[] arr = new T[this.length];
        // fill the array with the collection values
        return arr;
    }
}

Where is the catch, if i don't get it wrong this should be easy to implement in the default collection classes.

klingt.net
  • 1,699
  • 3
  • 15
  • 19

3 Answers3

4

Java generics uses type erasure, meaning that type parameters only exist at compile-time

At runtime, the code has no idea what T is, so it can't create a new T[].

SLaks
  • 800,742
  • 167
  • 1,811
  • 1,896
1

Why is it necessary to allocate an array that can hold the values of a collection and pass it to the toArray(T []) method of this collection?

It isn't. You can do so if you want to, but equally you can just pass in an empty array. Hence the documentation stating:

If the collection fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this collection.

You have to pass something in though, as the execution-time type of the array will be used to create another array of the same type if necessary. Using new T[...] will not create an array of the right execution-time type, due to type erasure. See the Java generics FAQ for more details, specifically the section on arrays of a concrete parameterized type.

Jon Skeet
  • 1,261,211
  • 792
  • 8,724
  • 8,929
  • I think i understood the problem, thanks to [your answer to another 'type erasure' related question](http://stackoverflow.com/a/339708/1706750). – klingt.net Nov 08 '13 at 14:30
0

Others answered perfectly your main question and why your second code block is not possible.

I agree with you Collection.toArray methods are not perfect and should be improved in future versions of the JRE. I think it can be done thank to defender methods that will be introduced in Java 8.

One way to implement it can be:

public someCollection<T> {
    ...
    public T[] toArray(Class<T> c) {
        T[] arr = Array.newInstance(c, getSize());
        // fill the array with the collection values
        return arr;
    }
}

Another way is that Collection subclases hold the type (class) they are containing just like CheckedCollections do and use it on toArray method so you don't have to give any parameter.

aalku
  • 2,720
  • 1
  • 18
  • 41