**Multidimensional Arrays** are arrays of arrays. Moreover, each element in a multidimensional array holds a reference to another array.

Multidimensional arrays are different to arrays in Java. Whereas arrays have a single dimension represented by square brackets ([]):

1 | ```
int[] numbers = new int[arrayLength];
``` |

multidimensional arrays declare a square bracket ([]) for each dimension

1 | ```
<DATA_TYPE>[1st Dimension][2nd Dimension]...[Nth Dimension] <VARIABLE_NAME> = new <DATA_TYPE>[size][size]...[size]
``` |

To explain multidimensional arrays let’s look at a contrived example, to assign seats in a cinema. As you know a cinema normally arranges seats in rows.

Let’s represent this data structure as a multidimensional array in Java. Let’s keep things simple, and represent the seating layout as 20 rows of 10 seats.

We can represent this in Java as:

1 | ```
boolean[][] seats = new boolean[20][10];
``` |

As we are dealing with two dimensions: rows, and seats we create the multidimensional array with two dimensions of 20 rows and 10 seats.

To access the value of a multidimensional array we have to specify the index of each dimension. For example to access the fifth seat of the first row we can do:

1 | ```
seats[0][4]
``` |

Normally, when working with Multidimensional arrays, we need to iterate it in order to access each element. Whereas with an array we normally use a single for loop, with a multidimensional array we need to use nested for loops.

In the case of our seating layout which has two dimensions, we require an outer for loop for the rows, and an inner for loop for the seats.

Let’s implement the seating layout in Java code, we will create methods to print out if a seat is occupied and a simple method to assign a seat.

Let’s start with the method to print the seating layout. As mentioned, the seating layout is represented as two dimensions. Therefore, we need a nested for loop.

1 2 3 4 5 6 7 8 9 10 11 | ```
public void printLayout() {
for(int row=0; row < seats.length; row ++) {
final int numberOfSeats = seats[row].length;
for (int seat = 0; seat < numberOfSeats; seat++) {
final boolean occupied = seats[row][seat];
final String status = String.format("Row: %s, Seat: %s, is %s",
row, seat, occupied ? "Occupied" : "Not Occupied");
System.out.println(status);
}
}
}
``` |

Above we create the method to print the seating layout. The outer for loop iterates through each row. The inner loop iterates the seats of each row. Since it’s technically possible for each row to have a different number of seats, we have to the get the number of seats for each row to iterate them.

1 2 3 4 | ```
final int numberOfSeats = seats[row].length;
for (int seat = 0; seat < numberOfSeats; seat++) {
///
}
``` |

Finally, we get the value if a seat is occupied by accessing it, using the row and seat index.

1 | ```
final boolean occupied = seats[row][seat];
``` |

Next we’ll look at assigning a seat.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | ```
public boolean assignSeat(int row, int seat) {
if(row<0 || row >=seats.length) {
return false;
}
boolean[] seatRow = seats[row];
if(seat <0 || seat >= seatRow.length) {
return false;
}
boolean occupied = seats[row][seat];
if(occupied) {
return false;
}
seats[row][seat] = true;
return true;
}
``` |

Above we create a method to assign a seat. It should also be noted, that this method has some issues if being accessed in a multi-threaded environment. You can read more about these issues here.

Anyway, we first check that the given row is inside the bounds of the seats array row dimension.

1 2 3 | ```
if(row<0 || row >=seats.length) {
return false;
}
``` |

Next, we get the array that represents the seats for the given row. We also check that the seat to be assigned is inside the bounds of this array.

1 2 3 | ```
if(seat <0 || seat >= seatRow.length) {
return false;
}
``` |

Then, we check if a seat has being previously assigned, by checking its value using the row and seat index.

1 | ```
boolean occupied = seats[row][seat];
``` |

If it has not being previously assigned, we mark the seat as assigned.

1 | ```
seats[row][seat] = true;
``` |

1 2 3 4 5 6 7 8 9 10 11 | ```
@Test
public void assignSeat() {
assertTrue(seatLayout.assignSeat(5,1));
assertFalse(seatLayout.assignSeat(5,1));
}
@Test
public void assignSeat_NotAssignedOutOfBounds() {
assertFalse(seatLayout.assignSeat(31,1));
assertFalse(seatLayout.assignSeat(1,30));
}
``` |

It is important to note when iterating an array, this operation has linear performance O(N) as we iterate through each element of an array.

However, when we are dealing with multidimensional arrays each nested loop has to iterate through all of its elements for its outer loop. For example in our seating layout example. There are 20 rows and each row contains 10 seats.

1 2 3 4 5 6 | ```
for(int row=0; row < seats.length; row ++) {
final int numberOfSeats = seats[row].length;
for (int seat = 0; seat < numberOfSeats; seat++) {
}
}
``` |

Above we can see for each row, we must iterate that rows seat array. Therefore, we would have around 200 operations to access all of the seat values:

1 | ```
20 * 10 = 200
``` |

We say that this algorithm executes in quadratic time:

1 | ```
O(N²) — Quadratic Time
``` |

because its: rows X seats. Moreover, we can tell that iterating an array in linear time in general is faster than iterating a multidimensional array in quadratic time.

In this tutorial we looked at an example of working with multidimensional arrays in Java.