views:

419

answers:

2

Please suggest some elegant way to convert
arrays of arrays to collections of collections and vice versa in Java.

I suppose there's no convenience methods in the Java API, right?

public static <T> T[][] nestedCollectionsToNestedArrays(
    Collection<? extends Collection<T>> source){

  // ... ?
}

public static <T> Collection<Collection<T>> nestedArraysToNestedCollections(
    T[][] source){

  // ... ?
}

Additional question:
What's with nested arrays of primitive types?

Do I have to declare methods for each primitive type, because of forbidden generic array creation?

A: 

Here's the method for array->Collection:

public static <T> Collection<Collection<T>>
        nestedArraysToNestedCollections(T[][] source) {
    Collection<Collection<T>> ret = new ArrayList<Collection<T>>();
    for (int i = 0; i < source.length; i++) {
        // could be ret.add(new ArrayList<T>(Arrays.asList(source[i]));
        Collection<T> list = new ArrayList<T>(source[i].length);
        for (int j = 0; j < source[i].length; j++) {
            list.add(source[i][j]);
        }
    }
    return ret;
}

The other direction is much trickier.

Michael Myers
What's wrong with the enhanced for loop??
Tom Hawtin - tackline
Nothing, but I figured if this is going to be a library method, he might as well do it the slightly faster way. Of course, the enhanced for loop might end up faster in the future, so it kind of evens out.
Michael Myers
+1  A: 

for Collection of Collections -> array of arrays: (it just returns an Object[][], because the type information for "T" is not present. you have to manually pass in the class of T if you want the array to be the right type, and it will be more complicated)

public static Object[][] nestedListsToNestedArrays(
    Collection<? extends Collection<?>> source){
  Object[][] result = new Object[source.size()][];
  int i = 0;
  for (Collection<?> subCollection : source) {
    result[i++] = subCollection.toArray();
  }
  return result;
}

Additional question: What's with nested arrays of primitive types? Do I have to declare methods for each primitive type,

Yes, you could either declare methods for each primitive type, or use reflection and sacrifice type safety. The reason is that each primitive array type is unrelated, and there is no supertype for all the primitive array types, except Object.

because of forbidden generic array creation?

No, but that's the reason for a different question: why the Collection of Collections -> array of arrays returning a T[][] is hard above.

newacct