Extra Material: 2D Arrays

We have already covered one-dimensional arrays. However, arrays are not restricted to one dimension: there are many cases in which a 2D array would be useful. We can even have multi-dimensional arrays above 2D: 3D, 4D and so on.

An example

Imagine that you are studying a multi-year Java course at an adult education department in a college. The Java course takes place over three years, and each year has five assessments. To store the marks for each assessment in code, you could use a 2D array with three rows (one for each year). Each row would itself be an array with five members, representing the individual mark for each assessment. The diagram below is a simple representation of a 2D array, and shows how you reference the individual values.
Simple representation of a 2D array

Here is a program which uses a 2D array to store the marks. The program reads in the marks and then displays them.

import java.util.Scanner;

public class TwoDArrayApp
{
    public static void main (String[] args)
    {
        int[][] marks = new int[3][5];
        String input;
        Scanner scanner = new Scanner(System.in);
        
        //Read in the marks
        for(int i=0; i<marks.length; i++)
        {
            System.out.println("Entering marks for year " + i);
            for(int j=0; j<marks[i].length; j++)
            {
                System.out.println("Enter mark for assessment " + j + " for year " + i);
                input = scanner.nextLine();
                
                marks[i][j] = Integer.parseInt (input);
            }
        }
        
        //Display the marks that were read in
        for(int i=0; i<marks.length; i++)
        {
            System.out.print("Marks for year " + i + ": ");
            for(int j=0; j<marks[i].length; j++)
            {
                System.out.print (marks[i][j] + " ");
            }
            System.out.print("\n");
        }
    }
}

Note the following:

2D Arrays with variable-length sub-arrays

The above example showed a 2D array where all the individual rows (sub-arrays) had the same length (5). However, this does not actually need to be the case. We can have 2D arrays with variable length rows. Imagine a modified version of the above scenario where in year 1, there are only 3 assessments, in year 2 there are 5, and in year 3 there are 7. We could use code like this:

import java.util.Scanner;

public class TwoDArrayApp2
{
    public static void main (String[] args)
    {
         //Second dimension of the 2D array unspecified
        int[][] marks = new int[3][];
        String input;
        Scanner scanner = new Scanner(System.in);
        
        // Initialise the individual rows
        marks[0] = new int[3];
        marks[1] = new int[5];
        marks[2] = new int[7];
        
        //Read in the marks
        for(int i=0; i<marks.length; i++)
        {
            System.out.println("Entering marks for year " + i);
            for(int j=0; j<marks[i].length; j++)
            {
                System.out.println("Enter mark for assessment " + j + " for year " + i);
                input = scanner.nextLine();
                
                marks[i][j] = Integer.parseInt (input);
            }
        }
        
        //Display the marks that were read in
        for(int i=0; i<3; i++)
        {
            System.out.print("Marks for year " + i + ": ");
            for(int j=0; j<marks[i].length; j++)
            {
                System.out.print (marks[i][j] + " ");
            }
            System.out.print("\n");
        }
    }
}

In this example, we initialise the 2D array slightly differently:

int[][] marks = new int[3][];
Note the missing second dimension, with the empty square brackets []. Rather than creating an array of three arrays, as before, this creates an array of three null arrays. Each member of marks will contain the value null at this point. So we have to explicitly create a new array for each member of marks:
marks[0] = new int[3];
marks[1] = new int[5];
marks[2] = new int[7];
Once we have done that, our loops to read in the marks and display them are exactly as they were before. Because we are using marks[i].length in the inner loop, rather than a constant value (e.g. 5), it will count from 0 to whatever the length of the current year's array is (3, 5 or 7).

A diagram of a variable-length 2D array is shown below.
Variable-length 2D array as an array of arrays

Pre-initialising a 2D array

As for 1D arrays, we can pre-initialise an entire 2D array in one statement, using the braces syntax. The following example does this with the marks scenario:

public class TwoDArrayApp3 
{
    public static void main (String[] args)
    {
        int[][] marks = 
            {
                { 32, 45, 56 },
                { 67, 78, 78, 56, 81 },
                { 80, 78, 81, 84, 66, 67, 93 }
            };
        
        for(int i=0; i<marks.length; i++)
        {    
            for (int j=0; j<marks[i].length; j++)
            {
                System.out.print(marks[i][j]+" ");            
            }
            System.out.print("\n");
        }
    }
}

Exercise