Home > database >  Generic function to swap rows and columns in an array
Generic function to swap rows and columns in an array

Time:12-27

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);
}
  •  Tags:  
  • java
  • Related