# Arrays - 2-dimensional

## 1-, 2-, and higher-dimensional arrays

Java, as with most languages, supports multi-dimensional arrays - 1-dimensional, 2-dimensional, 3-dimensional, ... In practice most arrays are one-dimensional, and two-dimensional (rows and columns) are also quite common. Higher dimensional arrays are less common so they aren't used in the examples, but there's nothing mysterious about them and the same principles apply.

Two-dimensional arrays are used whenever the model data is best represented with rows and columns, or has two varying aspects (eg, gender and age, weight and height, ...). It's also the idea, altho not the implementation, of graphics that specifies a two (or three) dimensional position with an x and y (and z) coordinate.

Terminology. Other terms you will see for a two-dimensional array are matrix or table.

## Visualizing two-dimensional arrays

2-dimensional arrays are usually represented with a row-column "spreadsheet" style. Assume we have an array, `a`, with two rows and four columns.

`int[][] a = new int[2][4];  // Two rows and four columns.`
 a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3]
Two-dimensional arrays are usually visualized as a matrix, with rows and columns. This diagram shows the array `a` with its corresponding subscripts.

## Style: Use named constants for array sizes

It's useful to define constants for the number of rows and columns. The reason named constants can better code is that these numbers may represent part of the problem domain and they will be used in other parts of the code. If a change is every necessary (eg, the number of teams in the Big Ten), changing one named constant will change all parts of the program. Each numeric "constant" should only appear once (the "DRY" principle).

```static final int ROWS = 2;
static final int COLS = 3;
. . .
int[][] board = new int[ROWS][COLS];```

Many row and column indexes (indices is the traditional English plural, but many prefer the more modern indexes) have a meaning, and aren't just simply arbitrary numbers. The following example might be used to represent the number of accidents on by day of the month and the hour of the day. See programming problems below for some examples using this array.

```static final int DAYS  = 31;
static final int HOURS = 24;
. . .
int[][] accidents = new int[DAYS][HOURS];```

## Initial values

You can assign initial values to an array in a manner very similar to one-dimensional arrays, but with an extra level of braces. The dimension sizes are computed by the compiler from the number of values. This would allocate a 3x3 board

`int[][] board = new int[][] {{1,0,0},{0,1,0},{1,2,1}};`

## Use nested for loops to process 2-dimensional arrays

Index names. Two-dimensional arrays are almost always processed with nested for loops. The two index variables are often called i and j (for the row and column), but it is better to use row and col or r and c. However, if the row and column have meanings, like month and year, use those names rather than a meaning neutral name.

Iterating down rows, then across columns is often better. The most common practice is for the outer loop be for the row and the inner loop for the column. If your program requires the outer iteration by columns, that's fine, but the default row-first iteration gives the best performance because "locality of reference" improves the perfomance of cache and virtual memory. It also allows use of the handy foreach loop.

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ``` ```// Purpose: Show use of nested loops to display 2D array. // Author : Fred Swartz, Feb 2008, Placed in public domain. // Shows : * Named constants for dimensions. // * Nested for loops to traverse entire 2D array by rows. // * Building the output in a String (StringBuilder more efficient). import javax.swing.JOptionPane; public class TwoDimTest { //... Define named constants to centralize definitions // and prevent use of "magic numbers". static final int ROWS = 2; static final int COLS = 4; public static void main(String[] args) { int[][] a2 = new int[ROWS][COLS]; String output = ""; // Accumulate text here (should be StringBuilder). //... Print array in rectangular form using nested for loops. for (int row = 0; row < ROWS; row++) { for (int col = 0; col < COLS; col++) { output += " " + a2[row][col]; } output += "\n"; } JOptionPane.showMessageDialog(null, output); } } ```

## Arrays of arrays

Java builds multi-dimensional arrays from many one-dimensional arrays, the so-called "arrays of arrays" approach.

There are a couple of interesting consequences of this: Rows may be different sizes. Also, each row is an object (an array) that can be used independently.

## Multi-dimensional arrays are built from multiple one-dimensional arrays

As with all arrays, the `new` keyword must be used to allocate memory for an array. For example,

`int[][] a = new int[2][4];`

This two-dimensional array will have two rows and four columns.

This actually allocates 3 objects: a one-dimensional array of 2 elements to hold each of the actual row arrays, and a two one-dimensional arrays of 4 elements to represent the contents of the rows.

 ``` +-----+ +-----+-----+-----+-----+ |a[0] | -> | [0] | [1] | [2] | [3] | | | +-----+-----+-----+-----+ +-----+ | | +-----+-----+-----+-----+ |a[1] | -> | [0] | [1] | [2] | [3] | +-----+ +-----+-----+-----+-----+``` In Java two-dimensional arrays are implemented is a one-dimensional array of one-dimensional arrays -- like this.

## Using .length instead of named constants

Named constants make a program very readable, but they may not be available if the array has been passed as a parameter. You can get the size of each dimension with the `.length` attribute. This is the most general style.

 ``` 1 2 3 4 5 6 ``` ``` for (int row = 0; row < a2.length; row++) { for (int col = 0; col < a2[row].length; col++) { output += " " + a2[row][col]; } output += "\n"; } ```

## Using foreach loop

If you are going across each row as in the above examples, the foreach loop provides simpler code. To understand this you must understand the array of arrays nature of multidimensional arrays. However, the foreach can not be used when indexing other than forward by single steps, and it only applies to reading the elements of the array, not writing them.

 ``` 1 2 3 4 5 6 ``` ``` for (int[] row : a2) { for (int val : row) { output += " " + val; } output += "\n"; } ```

## Programming problems

1. For the `accidents` array above write code that does the following:
1. Display the total number of accidents? Hint: Use nested loops to add all elements.
2. At what hour do the most accidents occur? Hint: Use on outer loop over hours, where the inner loop goes down the column and adds all the accidents for that hour. Keep max as you would for a one-dimensional array.
3. How would you declare a three-dimensional array that had an additional dimension for the 12 months?