How to create a nested array of arbitrary depth in java?

T Locks picture T Locks · Jul 5, 2013 · Viewed 8.8k times · Source

I am trying to create an array of arrays of arrays etc..., except I don't know how many nested levels deep it needs to be until runtime.

Depending on the input, I might need either int[], int[][], int[][][][][][], or anything else. (For context, I am trying to construct an N-dimensional grid for a cellular automaton, where N is passed as a parameter.)

I don't have any code for you because I have no idea how to go about this; I suspect is not possible at all using just arrays. Any help, or alternative solutions, would be appreciated.

Answer

Andy Thomas picture Andy Thomas · Jul 5, 2013

You could do this with an Object[], limiting its members to either Object[] or int[].

For example, here's an array that goes three levels deep in one part, and two levels deep in another:

   Object[] myarray = new Object[] {
         new Object[] { new int[] { 1, 2 }, 
                        new int[] { 3, 4 }},
         new int[] { 5, 6 } 
    };

After you've created it, you may want to access members. In your case, you know the depth N up front, so you know at what depth to expect an Object[] and at what depth to expect an int[].

However, if you didn't know the depth, you could use reflection to determine whether a member is another Object[] level or a leaf int[].

    if ( myarray[0] instanceof Object[] ) {
           System.out.println("This should print true.");
    }

EDIT:

Here's a sketch [untested so far, sorry] of a method that access a member of an array of known depth, given an array of indices. The m_root member can be an Object[] or an int[]. (You could relax this further to support scalars.)

   public class Grid {
        private int m_depth;
        private Object m_root;
        ...
        public int get( int ... indices ) {
            assert( indices.length == m_depth );
            Object level = m_root;
            for ( int i = 0; i + 1 < m_depth; ++i ) {
                level = ((Object[]) level)[ indices[i] ];
            }
            int[] row = (int[]) level;
            return row[ indices[m_depth - 1] ];
        }
   }