I want to make a function which can take any type of array (int
, String
, boolean
, etc) and return an array of the same type with the rows and columns switched.
public static String[][] swap_rows_columns_str_arr(String[][] arr) {
String[][] new_arr = new String[arr[0].length][arr.length];
for (int col = 0; col < arr[0].length; col ) {
for (int row = 0; row < arr.length; row ) {
new_arr[col][row] = arr[row][col];
}
}
return new_arr;
}
I've managed to get it work for singular datatypes, but how would I get it to work for any datatype?
CodePudding user response:
You can use a generic type <T>
, but you have to use Array.newInstance()
to create the array (see What's the reason I can't create generic array types in Java?). The source code can look like this:
public static <T> T[][] swap_rows_columns_str_arr(T[][] arr) {
@SuppressWarnings("unchecked")
T[][] new_arr = (T[][]) Array.newInstance(
arr.getClass().getComponentType().getComponentType(),
arr[0].length,
arr.length);
for (int col = 0; col < arr[0].length; col ) {
for (int row = 0; row < arr.length; row ) {
new_arr[col][row] = arr[row][col];
}
}
return new_arr;
}
This only works for non-primitive types, as primitive types cannot be used in generics. For the primitive types you have to create eight overloads of this method.
CodePudding user response:
As noticed by @DontKnowMuchBut Getting Better in the comments, better work with nested List
of generic type: List<List<T>>
. But if you need to work with arrays
, you can use stream
and then cast the transposed array
. However, it won't work with primitives.
public static <T> T[][] transpose(T[][] arr) {
Object[][] transposed = IntStream.range(0, arr[0].length)
.mapToObj(column -> IntStream.range(0, arr.length)
.mapToObj(row -> arr[row][column])
.toArray(Object[]::new))
.toArray(Object[][]::new);
return (T[][]) transposed;
}
Update:
As noticed by @Alex Rudenko, you need to implement overloaded methods for primitives. For int[][]
you can do:
public static int[][] transpose(int[][] arr) {
return IntStream.range(0, arr.length)
.mapToObj(column -> IntStream.range(0, arr[0].length)
.map(row -> arr[row][column])
.toArray())
.toArray(int[][]::new);
}