snippetjavaMinor
Better way to write generic method to convert List<List<T>> to T[][]
Viewed 0 times
genericmethodconvertwaywritebetterlist
Problem
I was working through getting myself past the creation of a generic method, that converts a
Now I can call this method as:
Now, here's the problem. Consider the code:
Now, this is what I want to avoid - double iteration of
List or List>, to T[] or T[][] respectively. Well, let's just consider a maximum dimension of 2 for now.List to T[] is quite straight-forward:public static T[] listToArray(List list, Class clazz) {
/**** Null Checks removed for brevity ****/
T[] arr = (T[]) Array.newInstance(clazz, list.size());
for (int i = 0; i < list.size(); ++i) {
arr[i] = list.get(i);
}
return arr;
}Now I can call this method as:
List list = new ArrayList<>(Arrays.asList("rohit", "jain"));
String[] arr = listToArray(list, String.class);List> to T[][] is what gives problems:Now, here's the problem. Consider the code:
public static T[][] multiListToArray(List> listOfList, Class clazz) {
// Here I don't know what size to give for 2nd dimension
// T[][] arr = (T[][]) Array.newInstance(clazz, listOfList.size(), ?);
// So, I tried this. But this of course is not type safe
// T[][] arr = (T[][]) new Object[listOfList.size()][];
/* Only alternative I had was to iterate over the listOfList to get the
maximum out of all the column sizes, which I can give as 2nd
dimension later on.
*/
int maxCol = 0;
for (List row: listOfList) {
if (row.size() > maxCol) {
maxCol = row.size();
}
}
// Now I can pass `maxCol` as 2nd dimension
T[][] arr = (T[][]) Array.newInstance(clazz, listOfList.size(), maxCol);
for (int i = 0; i row = listOfList.get(i);
arr[i] = listOfList.get(i).toArray((T[])Array.newInstance(clazz, row.size()));
}
return arr;
}Now, this is what I want to avoid - double iteration of
List> to be able to create the array. Is there any possibility?Solution
Since you are creating new instance of arrays in your second loop, you don't need to know the size of the "inner list". Your "outer array" has to be as big as the "outer list". In a second phase, you instanciate the "inner arrays".
There's a simple way do this:
More over, as you can see in the code above, you can provide a 0-length array to
This piece of code:
Will produce this output:
[a, b, c]
[d, e, f, g]
[h, i]
EDIT: There is an Ideone example.
EDIT 2: Code and Ideone updated to comply with OP needs.
There's a simple way do this:
public T[][] multiListToArray(final List> listOfList, final Class classz) {
final T[][] array = (T[][]) Array.newInstance(classz, listOfList.size(), 0);
for (int i = 0; i < listOfList.size(); i++) {
array[i] = listOfList.get(i).toArray((T[]) Array.newInstance(classz, listOfList.get(i).size()));
}
return array;
}More over, as you can see in the code above, you can provide a 0-length array to
toArray(T[]) method.This piece of code:
final List> test = new ArrayList>();
test.add(new ArrayList(Arrays.asList("a", "b", "c")));
test.add(new ArrayList(Arrays.asList("d", "e", "f", "g")));
test.add(new ArrayList(Arrays.asList("h", "i")));
for (final String[] innerArray : multiListToArray(test, String.class)) {
System.out.println(Arrays.toString(innerArray));
}Will produce this output:
[a, b, c]
[d, e, f, g]
[h, i]
EDIT: There is an Ideone example.
EDIT 2: Code and Ideone updated to comply with OP needs.
Code Snippets
public <T> T[][] multiListToArray(final List<List<T>> listOfList, final Class<T> classz) {
final T[][] array = (T[][]) Array.newInstance(classz, listOfList.size(), 0);
for (int i = 0; i < listOfList.size(); i++) {
array[i] = listOfList.get(i).toArray((T[]) Array.newInstance(classz, listOfList.get(i).size()));
}
return array;
}final List<List<String>> test = new ArrayList<List<String>>();
test.add(new ArrayList<String>(Arrays.asList("a", "b", "c")));
test.add(new ArrayList<String>(Arrays.asList("d", "e", "f", "g")));
test.add(new ArrayList<String>(Arrays.asList("h", "i")));
for (final String[] innerArray : multiListToArray(test, String.class)) {
System.out.println(Arrays.toString(innerArray));
}Context
StackExchange Code Review Q#29666, answer score: 4
Revisions (0)
No revisions yet.