Scheintod
Scheintod

Reputation: 8105

Generic multi dimensional array conversion function

This function converts a 2-dimensional Collection of Strings to a 2-dimensional array of Strings:

public static String[][] toArray(
                             Collection<? extends Collection<String>> values){

    String[][] result = new String[ values.size() ][];
    int i=0;
    for( Collection<String> row : values ){
        result[i] = row.toArray( new String[ row.size() ] );
        i++;
    }
    return result;
}

How would this function be written in order to do this generically:

public static <X> X[][] ArrayArray(Collection<? extends Collection<X>> values){
    // ?
}

Upvotes: 2

Views: 262

Answers (3)

Scheintod
Scheintod

Reputation: 8105

So it's not possible because of type erasure. But there is at least a solution for:

public static <X> X[][] toArray( Class<X> xClass, 
        Collection<? extends Collection<X>> values ){

    @SuppressWarnings( "unchecked" )
    X[][] result = (X[][])Array.newInstance( xClass , values.size(), 0 );

    int i=0;
    for( Collection<X> row : values ){

        @SuppressWarnings( "unchecked" )
        X[] rowAsArray = (X[])Array.newInstance( xClass, row.size() );
        result[i] = row.toArray( rowAsArray );
        i++;
    }
    return result;
}

(thanks for pointing me to Array.newInstance)

Upvotes: 0

arshajii
arshajii

Reputation: 129507

Generics and arrays don't mix. One alternative is to pass a Class instance representing X and use that to create the return array (see Array.newInstance()). I believe a better approach would be to pass an X[][] in as another argument, fill it, and return it:

public static <X> X[][] toArray(Collection<? extends Collection<X>> values,
        X[][] result) {

    int i = 0;
    for (Collection<X> row : values)
        result[i] = row.toArray(result[i++]);

    return result;
}

For example:

List<List<Integer>> l = Arrays.asList(Arrays.asList(1,2,3), 
                                      Arrays.asList(4,5),
                                      Arrays.asList(6));

System.out.println(Arrays.deepToString(toArray(l, new Integer[l.size()][0])));
[[1, 2, 3], [4, 5], [6]]

Upvotes: 2

delucas
delucas

Reputation: 51

I'm afraid you can't.

It's because Java's arrays (unlike generics) contain, at runtime, information about its component type. So you must know the component type when you create the array. Since you don't know what T is at runtime, you can't create the array

Source: https://stackoverflow.com/a/2931240, by newacct

Upvotes: 2

Related Questions