Array of arbitrary dimension as a method parameter

I have a simple conversion method for an array from boolean to int :

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

Now I have the same method for two-dimensional arrays:

 public static int[][] convert2dToInt (boolean[][] x) { int la = x.length; int lb = x[0].length; int[][] y = new int[la][lb]; for (int a = 0; a < la; a++) { for (int b = 0; b < lb; b++) { if (x[a][b]) { y[a][b] = 1; } else { y[a][b] = 0; } } } return y; } 

How can I generalize these methods to arrays of arbitrary dimension without writing all the methods manually?

+7
java arrays methods
source share
3 answers

It is possible, but reflection and recursion are 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 measurements up to 255 - I gave him a quick test with 5 and it seemed to work. It should also work with jagged and null s arrays.

To use it, call ArrayTransfer.transferToIntArray(...) using the boolean array, and it will return the corresponding int array. Of course, you need to pass the return value of this method to the corresponding type of the int array.

Of course, there is room for improvement. In particular, it would be better if some cache of various classes of arrays were stored, instead of creating empty arrays just to get their class.

+2
source share

This will 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; } 

Just repeat your code - I did not have much time, since this is my lunch break, so I do not know if everything is correct, but the method should correspond:

 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; } 

Well, this solution was not the answer to the problem, since I did not read exactly what was asked. Sorry about that. As far as I know, a generic method is not possible as long as you work with primitive data types. This is because you cannot add int [] as a member for int []. Therefore, you should work with Object [], Boolean [] and Integer [], but I do not know how you want to work with this. I donโ€™t think itโ€™s wise to write such a method, because when you can transform such a data structure as you want goals to be available. Since you do not know how many dimensions your array will have, you will not be able to write general methods for accessing members. I will try to write a solution for this, since I want to know if I will find another possible solution. Is it right that the question is, is this possible, and if not, is it reasonable?

I think we can find a better solution for this if you tell us that you want to have this code. As I said, when I have more time, I will try to find another solution.

+1
source share

You can use conditional recursion according to the type of the passed parameter and use convert1dToInt to measure, then you collect the result in one object, in this context you will be forced to pass only the object, enter Object and return the object that you produced it, here is a little code representing the idea of โ€‹โ€‹recursive a function that simply prints the value of elements in an array:

 public static void convertDimN(Object o) { if (o.getClass().isArray() && Array.get(o, 0).getClass().isArray()) { // is oa 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)); } } 
+1
source share

All Articles