Dynamic Multidimensional Array Printing

javaAddict 0 Tallied Votes 914 Views Share

Hi All. This is my first code snippet. I don't know how practical it is, but I
came up with the idea, so I wanted to do it.

Assuming you have an array. You use a for loop to display its data.
For 2D arrays you use 2 for loops. But that is not dynamic. Every time an extra
dimension is added, you need to write an extra loop. How about a method that
takes as argument an Object, that is actually an array of unknown dimensions (NxD).
By using recursion the program will "generate" dynamically the right amount of
for loops needed to print all the data of the array without having to know how
many dimensions it has.

The first method (printArray(Object obj)), is only to simply demonstration how
is done. We initially check if the object is an array. If yes, we loop it and
we take each of its elements. If that is also an array, we recursively call the
same method. Else we simply print the element itself.
Now because for multidimensional arrays what is printed will not be very well
formatted, a second method was implemented:

printArray(Object obj, int level).
We first call that method with level=0 and for each recursive call we
increase the level. By doing that, we print each dimension/level of the array one extra \t character to the right. The second method prints more information about the array.
And if you want to make sure that the initial call is with level=0 then make that method private and call it from a public method.

import java.lang.reflect.Array;

class Test {
    // simple method
    private static void printArray(Object obj) {
        // if obj is not an array return
        if (obj==null || !obj.getClass().isArray()) return;
        int length = Array.getLength(obj); // get the length of the array
        
        int i=0;
        
        for (i=0;i<length;i++) {
            Object o = Array.get(obj, i); // get the ith element
            if (o==null || !o.getClass().isArray()) {
                System.out.print(o+" ");
            } else {
                printArray(o);
            }
        }
        System.out.println();
    }

    // user friendly that prints extra information
    private static void printArray(Object obj, int level) {
        // if obj is not an array return
        if (obj==null || !obj.getClass().isArray()) return;
        int length = Array.getLength(obj); // get the length of the array

        // adding extra tabs depending on the dimension we are trying to print
        String tab = "";
        String del = "\t";
        for (int i=0;i<level;i++) {
            tab += del;
        }
        int i=0;
        System.out.println(tab+"Array "+level);
        
        if (i<length) {
            Object o = Array.get(obj, i); // get the ith element
            if (o==null || !o.getClass().isArray()) {
                System.out.print(del+tab+o+" "); // print call with tabs
            } else {
                printArray(o, level+1);
            }
        }
        for (i=1;i<length-1;i++) {
            Object o = Array.get(obj, i);
            if (o==null || !o.getClass().isArray()) {
                System.out.print(o+" "); // print call without tabs
            } else {
                printArray(o, level+1);
            }
        }
        if (i<length) {
            Object o = Array.get(obj, i);
            if (o==null || !o.getClass().isArray()) {
                System.out.println(o); // println call for changing lines
            } else {
                printArray(o, level+1);
            }
        }
    }

    // calling previous private method to make sure that level is 0
    public static void printArrayOfObjects(Object obj) {
        printArray(obj, 0);
    }

    // main method
    public static void main(String [] args) throws Exception {
        Object obj1 = new int [2][3][4];
        printArrayOfObjects(obj1);
        
        // OR with values
        int [][][] obj2 = new int [2][3][4];
        obj2[0][0][0] = 5;
        obj2[0][0][1] = 4;
        obj2[0][0][2] = 2;
        obj2[0][0][3] = 9;
        
        obj2[0][1][0] = 1;
        obj2[0][1][1] = 2;
        obj2[0][1][2] = 3;
        obj2[0][1][3] = 4;
        
        obj2[0][2][0] = 4;
        obj2[0][2][1] = 3;
        obj2[0][2][2] = 2;
        obj2[0][2][3] = 1;
        
        obj2[1][0][0] = 50;
        obj2[1][0][1] = 40;
        obj2[1][0][2] = 20;
        obj2[1][0][3] = 90;
        
        obj2[1][1][0] = 10;
        obj2[1][1][1] = 20;
        obj2[1][1][2] = 30;
        obj2[1][1][3] = 40;
        
        obj2[1][2][0] = 40;
        obj2[1][2][1] = 30;
        obj2[1][2][2] = 20;
        obj2[1][2][3] = 10;
        
        printArrayOfObjects(obj2);
    }
}
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Neater to use the modern Java for-each loop:

for (Object o : obj) { 
   ...

rather than the old C-style looping:

int length = Array.getLength(obj);
int i=0; // NB this is redundant!
for (i=0;i<length;i++) {
  Object o = Array.get(obj, i); 
  ...
javaAddict 900 Nearly a Senior Poster Team Colleague Featured Poster

Neater to use the modern Java for-each loop:

for (Object o : obj) { 
   ...

rather than the old C-style looping:

int length = Array.getLength(obj);
int i=0; // NB this is redundant!
for (i=0;i<length;i++) {
  Object o = Array.get(obj, i); 
  ...

I am old school and old habits die hard.

I am also using that in order to distinguish when to call the print or the println.
As you can see when i=0 I call the print with the extra tabs at the right
When i>0 I simply call println(o+" ");
And at the last i I use println

Orlando Augusto 15 Newbie Poster
import java.lang.reflect.Array;

public class TestReflectionToStringArray {
    // simple method
    private static final void toStringReflectionArray(Object array, int index,
            StringBuilder sb) {

        int length = array.getClass().isArray() ? Array.getLength(array) : -1;

        sb.append(length == 0 ? "{}" : "");

        if (length > 0) {
            Object child = null;
            sb.append(index == 0 ? "{" : ",{");
            for (int i = 0; i < length; i++) {
                if (array != null && array.getClass().isArray()) {
                    child = Array.get(array, i);
                    if (child.getClass().isArray()) {
                        toStringReflectionArray(child, i, sb);
                    } else {
                        sb.append(child + (i < length - 1 ? "," : "")).append(
                                i == length - 1 ? "}" : "");
                    }
                }
            }
            sb.append(child.getClass().isArray() ? "}" : "");
        }
    }

    // calling previous private method to make sure that level is 0
    public static final String toStringArray(Object array) {
        StringBuilder sb = new StringBuilder();

        sb.append(array.toString()).append("[");
        toStringReflectionArray(array, 0, sb);
        sb.append("]");

        return sb.toString();
    }

    // main method
    public static void main(String[] args) throws Exception {
        Object obj1 = new int[2][3][4];

        System.out.println(toStringArray(obj1));

        // OR with values
        int[][][] obj2 = new int[2][3][4];
        obj2[0][0][0] = 5;
        obj2[0][0][1] = 4;
        obj2[0][0][2] = 2;
        obj2[0][0][3] = 9;

        obj2[0][1][0] = 1;
        obj2[0][1][1] = 2;
        obj2[0][1][2] = 3;
        obj2[0][1][3] = 4;

        obj2[0][2][0] = 4;
        obj2[0][2][1] = 3;
        obj2[0][2][2] = 2;
        obj2[0][2][3] = 1;

        obj2[1][0][0] = 50;
        obj2[1][0][1] = 40;
        obj2[1][0][2] = 20;
        obj2[1][0][3] = 90;

        obj2[1][1][0] = 10;
        obj2[1][1][1] = 20;
        obj2[1][1][2] = 30;
        obj2[1][1][3] = 40;

        obj2[1][2][0] = 40;
        obj2[1][2][1] = 30;
        obj2[1][2][2] = 20;
        obj2[1][2][3] = 10;

        System.out.println(toStringArray(obj2));
    }
}
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Why re-invent the wheel?

  System.out.println(java.util.Arrays.deepToString(obj2));
rproffitt commented: This spoke to me. +11
Orlando Augusto 15 Newbie Poster

For pure pleasure friend. To reinvent the wheel maybe you can discover an optimization. ;-)

Regards

JamesCherrill commented: That's a good answer! +15
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I created a discussion around design issues, using this as the working example. See
https://www.daniweb.com/programming/software-development/code/506561/nested-array-printing-etc-designing-for-reuse

JC

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.