Introduction to Multi-dimensional Arrays 

CS 170  Dr. Harrington

Local Links:  Hyper linked answers to 2D array questionsPrintable answers to 2D array questionsLinesStu.java, Lines.java, UI.java

You should be familiar with one-dimensional arrays. The data in arrays may be any elementary type or any type or object. In particular these objects may be arrays. Arrays of arrays (of arrays of arrays ....) are called multidimensional arrays.  Aside from a special initializer, the syntax of multidimensional arrays is already implied from the syntax for one-dimensional arrays. We will mostly speak of two dimensional arrays. As one-dimensional arrays may be thought of as linear lists or sequences, two dimensional arrays may be thought of as a two dimensional table or matrix. If I have a table of integers, for instance with three rows and four columns

2 4 7 15

3 1 8 10

6 0 9 12

I can think of this as three rows, and each row is a linear sequence of ints -- each row is a one dimensional array of ints of length 4. The whole table contains three such rows, so it is an array of 3 rows.

We could declare a variable of the right size as

int[][] table = new int[3][4];

To assign the 8 in the table above, consider that it is in the second row in normal counting, but we start array indices at 0, so there are rows 0, 1, and 2, and the 8 is then in row 1. Row one has the data of a one dimensional array, again starting with index 0, so the 8 is at index 2. We can assign a value to that position with

table[1][2] = 8;

Note that since the dimensions come after the variable, they are associated with variable from left to right, so table[1] refers to the one dimensional array which contains the data for the second row.

What is stored in a variable refering to an array? Since an array is an object, only a reference is stored. Schematically, we can think of the reference as a poiner or arrow to the actual object.  The statement initializing the new two dimensional array actually creates FOUR objects: the array of row references, and each array for an individual row:

Recall that when objects are created, all instance variables are given the default value for the type.  The default for ints is 0, so the table, when first created, would contain all 0's.  We could then give each element any other values. like the values in the table above:

table[0][0] = 2;  table[0][1] = 4;  table[0][2] = 7;  table[0][3] = 15;
table[1][0] = 3;  table[1][1] = 1;  table[1][2] = 8;  table[1][3] = 10;
table[0][0] = 2;  table[2][1] = 0;  table[2][2] = 9;  table[2][3] = 12;
A shorthand, analogous to initializing one dimensional arrays would be
int[][] table = { {2, 4, 7, 15},  {3, 1, 8, 10}, {6, 0, 9, 12} };
Often two-dimensional arrays, like one-dimensional arrays, are processed in loops.  Multiple dimension arrays are often processed in nested loops.
Question 1:  How could you sum the elements of table?  You will need two index variables for the row and column. Answer to 2D array question 1

Question 2:  If we wanted a method that could sum the elements of any rectangular array, we could write a method that passes the 2D array as a parameter, say int[][] t.
a.   How would we get the number of rows and columns?  Recall a multidimensional array is just composed of one dimensional arrays.  Look again at the diagram for table and think of it as the diagram for an array t: Hint for Question 2a  Answer for 2D array Question 2a

b.  Complete the more general method with heading

sum2D(int[][] t) {    Answer for 2D array Question 2b
c.  In this case the indices are not of interest, only the data elements.  Using the fact that whole (1D) arrays can be used  in  for-each loops, and that 2D arrays are composed of 1D arrays, rewrite the answer (a challenge the first time).  Answer for 2D array Question 2c

Question 3:  Write a method that sets the values in a given rectangular array to 10 * (row index +1) + the column index +  1.  Assume you count rows and columns starting from 1, so an array with two rows and five columns would end up with values below.  Your method should set the values in the array, not print them out.
11 12 13 14 15
21 22 23 24 25        Answer to 2D array question 3
Note that the order of subscripts [row][column] will look odd if you use the usual mathematical graphing notation, x for horozontal position (the column), and y for vertical position (the row).  Using x and y this would translate into subscripts  [y][x].  Mathematical notation usually has x first as in (x,y).

.Note that I could just as well have thought of the table as containing 4 columns, each with 3 rows.  Then it would be created by

int[][] table = new int[4][3];
Then table[i] is a column of the table, not a row.  You can choose to do things either way as long as you are consistent.

Below is sample output from a program that draws straight lines of characters on a grid.  I have chosen to use conventional mathematical coordinates (x,y), with (0,0) displayed at the bottom left corner.  Each point in a line is offset from the previous point by a horozontal amount dx and a vertical amount dy.  I allow the user to specify a line even where only some or none of the points are on the grid that is displayed.

Enter number of rows  (0 to quit): 8
Enter width: 12
Enter the number of points (0 to stop): 3
Enter starting x: 1
Enter starting y: 2
Enter dx: 1
Enter dy: 1
Enter char: A
............
............
............
...A........
..A.........
.A..........
............
............
Enter the number of points (0 to stop): 6
Enter starting x: 8
Enter starting y: 0
Enter dx: -1
Enter dy: 1
Enter char: B
............
............
...B........
...AB.......
..A..B......
.A....B.....
.......B....
........B...
Enter the number of points (0 to stop): 5
Enter starting x: 3
Enter starting y: 1
Enter dx: 1
Enter dy: 0
Enter char: C
............
............
...B........
...AB.......
..A..B......
.A....B.....
...CCCCC....
........B...
Enter the number of points (0 to stop): 25
Enter starting x: 10
Enter starting y: -5
Enter dx: 0
Enter dy: 1
Enter char: D
..........D.
..........D.
...B......D.
...AB.....D.
..A..B....D.
.A....B...D.
...CCCCC..D.
........B.D.
Enter the number of points (0 to stop): 0
Enter number of rows  (0 to quit): 0

Here is a partial program, with the main method, but it is a self-study exercise for you to figure out the three methods called by the main program.  This partial program is also in the file fs  The method stubs are in order of difficulty.  Easiest is fill, next is printGrid, and hardest is addLine.  My full solution is the file Lines.java.
 

//LinesStu.java

// a start on a student version of the class Lines.
//   to avoid overwriting my solution
// assumes the presence of the user input class UI.java

/**
Contains a main program to draw text lines
*/
class LinesStu {

    /**
    *  Program to draw text lines at angles
    */
    public static void main(String[] arg) {
      // print character grid with lines in any direction
      int h = UI.readInt("Enter number of rows  (0 to quit): ");
      while (h > 0) {
        int w = UI.readInt("Enter width: ");
        char[][] g = new char[h][w];
        fill(g,'.');
        int n = UI.readInt("Enter the number of points (0 to stop): ");
        while (n > 0){
          int x = UI.readInt("Enter starting x: ");
          int y = UI.readInt("Enter starting y: ");
          int dx = UI.readInt("Enter dx: ");
          int dy = UI.readInt("Enter dy: ");
          char c = (UI.readChar("Enter char: ");
          addLine(g,n, x, y, dx, dy, c);
          printGrid(g);
          n = UI.readInt("Enter the number of points (0 to stop): ");
        }
        h = UI.readInt("Enter number of rows  (0 to quit): ");
      }
    }

    /**
    * Fill a 2D array with a specified character.
    * @param
    *  g the array to fill
    * @param
    *  c the char to fill with
    */
    static void fill(char[][] g, char c) {
      // code!

    }

    /**
    *   Print a 2D character array.
    *   The array is printed to the screen, one row
    *  (first index fixed) per line, with row 0 at the bottom.
    * @param
    *  g the array
    */
    static void printGrid(char[][] g) {
      // code!

    }

    /**
    *   Add a line at an angle to a 2D character array.
    *   The part of sequence of positions that are inside the array
    *   are set to the specified character.
    * @param
    *  n the number of points
    * @param
    *  g the array
    * @param
    *  x first index of starting point
    * @param
    *  y second index of starting point
    * @param
    *  dx the increment in the SECOND index
    * @param
    *  dy the increment in the FIRST index
    * @param
    *  c the char to write in the array
    */
    static void addLine(char[][] g, int n, int x, int y,
                         int dx, int dy, char c) {
      // code!
    }
}

Advanced topics 

Multiple dimensional arrays in Java (unlike C++) do not need to be "rectangular".  Here is code to make a triangular 2-d array:
 int[][] tri = new int[4][];  // generates a single array with null entries
  for (int i = 0; i < tri.length; i++)
   tri[i] = new int[i+1];