Array of arbitrary dimension as method parameter Array of arbitrary dimension as method parameter arrays arrays

Array of arbitrary dimension as method parameter


This is possible, but reflection and recursion are both inevitable:

import java.lang.reflect.Array;public class ArrayTransfer {    private static int getArrayDimension(Object array) {        Class<?> clazz = array.getClass();        int dimension = 0;        while (clazz.isArray()) {            clazz = clazz.getComponentType();            dimension += 1;        }        if (clazz != boolean.class) {            throw new IllegalArgumentException("Base array type not boolean");        }        return dimension;    }    // Transfers a boolean array of the specified dimension into an int    // array of the same dimension.    private static Object transferToIntArray(Object booleanArray, int dimension) {        if (booleanArray == null) {            return null;        }        // Determine the component type of the new array.        Class<?> componentType;        if (dimension == 1) {            componentType = int.class;        } else {            // We have a multidimensional array; the dimension of the component            // type is one less than the overall dimension.  Creating the class            // of an array of an unknown dimension is slightly tricky: we do            // this by creating a 0 x 0 x ... x 0 array (with dimension - 1            // zeros) and then getting the class of this array.  Handily for us,            // int arrays are initialised to all zero, so we can create one and            // use it straight away.            int[] allZeroDimensions = new int[dimension - 1];            componentType = Array.newInstance(int.class, allZeroDimensions).getClass();        }        // Create the new array.        int length = Array.getLength(booleanArray);        Object newArray = Array.newInstance(componentType, length);        // Transfer the elements, recursively if necessary.        for (int i = 0; i < length; ++i) {            if (dimension == 1) {                Boolean value = (Boolean)Array.get(booleanArray, i);                Array.set(newArray, i, (value.booleanValue()) ? 1 : 0);            }            else {                Object oldChildArray = Array.get(booleanArray, i);                Object newChildArray = transferToIntArray(oldChildArray, dimension - 1);                Array.set(newArray, i, newChildArray);            }        }        return newArray;    }    // Transfers a boolean array of some dimension into an int    // array of the same dimension.    public static Object transferToIntArray(Object booleanArray) {        if (booleanArray == null) {            return null;        }        int dimension = getArrayDimension(booleanArray);        return transferToIntArray(booleanArray, dimension);    }}

This should work with any number of dimensions up to 255 - I gave it a quick test with 5 and it seemed to work. It should also work with 'jagged' arrays, and with nulls.

To use it, call ArrayTransfer.transferToIntArray(...) with your boolean array, and it will return the corresponding int array. You will of course need to cast the return value of this method to the relevant int array type.

There's certainly scope for improving this. In particular, it would be nicer if some cache of the various array classes was kept, rather than having to instantiate empty arrays just to get their class.


You can use a conditional recursivity on the type of the passed parameter and you use convert1dToInt for the dimension one , then you collect the result in one object, in the given context you will be forced to pass just an object of type Object and return an Object then you cast it , here is a small code that present idea of the recursive function that just print the value of the elements in the array :

public static void convertDimN(Object o) {    if (o.getClass().isArray() && Array.get(o, 0).getClass().isArray()) {        // is o a two dimentional array     for (int i = 0; i < Array.getLength(o); i++) {            convertDimN(Array.get(o, i));        }    } else        for (int i = 0; i < Array.getLength(o); i++) {            System.out.println(Array.get(o, i));        }}


This would be your first method:

    public static int[] convert1dToInt (boolean[] x) {        //int la = x.length; is useless since you are accessing an object member and not a method     int[] y = new int[x.length];        for (int a = 0; a < x.length; a++) {          y[a] = x[a] ? 1 :0;    }    return y;}

Simply reuse your code - I had not much time since it is my lunch break so I don#t know if all is correct but the way should fit:

public static int[][] convert2dToInt (boolean[][] x)  {         int[][] y = new int[x.length][];            for (int a = 0; a < x.length; a++) {              y[a] = convert1dToInt (x[a]) ;        }        return y;    }

Ok, this solution was not the answer for the problem since I did not read exactly what has been asked. Sorry for that. As far as I know a generalized method is not possible as long as you are working with primitive datatypes. This is because you can't add an int[] as a member for an int[]. So you should then work with Object[], Boolean[] and Integer[] but I don't know how you want to work with that. I don't think it is sensible to write such a method because when you are able to convert such a data-structure how do you want the targets to be accessed. Since you do not know how many dimensions your array will have you can't write generic methods to access the members. I will try to write a solution for that since I want to know if I find an other possible solution. Am I right that the question is, if it is possible and not if it is reasonable?

I think we can find the best solution for that if you tell us the usecase you want to have this code for. As I said, when I have more time later on I'll try to find another solution.