Java Programming   Java Programming
 |Sofia Home | Content Gallery |
Home
Syllabus
Schedule
Lessons
Assignments
Resources

Lesson 8.4 Arrays

2D Arrays

When you declare an array, the elements can be of any type. You can create an array of Button references like this:
 
Button[] buttons = new Button[5];

and you can create an array of int like this:

int[] pieces = new int[10];

The variables buttons and pieces are both array variables that refer to a collection of Button objects or to a collection of int values.

Java also allows you to create array variables that refer, not to Button objects or int values, but to other arrays. These are called multidimensional arrays. Since we'll only be working with two dimensions in this course, we'll refer to these as 2D arrays.

In this section, you'll learn how to create a 2D array, how to access the elements in such an array, and how to use 2D arrays with methods. You'll also learn how you can slice a 2D array to process a portion of the array, while ignoring the rest.

The easiest way to think of a 2D array is to think of rows and columns. A grid or a spreadsheet is a useful mental model. In reality, though, a 2D array is composed of arrays of arrays. You'll see what that really looks like shortly.

Back to Top

Creating a 2D Array

To create a 2D array, just extend the syntax you've already learned for 1D arrays. For instance:
 
int[] d1 = new int[5];

The variable d1 is an int[] (int array) that refers to 5 int values. Since that's true, then what does this mean?

int[][] grid;

The variable grid is an array, but each element is not an int, but an int[] or int array. When creating a 2D array, it is common to create both the rows and columns at the same time like this:

int[][] grid = new int[2][4];

This creates a variable (grid), that refers to a two-element array. Each element in that two-element array (grid[0] and grid[1]) is an int[] or int array variable

In this case, both grid[0] and grid[1] refer to separate four-element int arrays. 

The illustration [click on image to enlarge] should help you to visualize the relationships between the various pieces.

Illustrates the grid array as an array of array variables

Back to Top

Using 2-D Elements

Rather than thinking of 2-D arrays as shown in the previous illustration, [even though that is how the arrays are implemented in memory], it is usually easier to think of them as an actual grid composed of rows and columns, labeled starting at 0, like this:
Thinking of 2-D arrays in this way makes it easy to remember where the individual elements are located.

To access an individual element, instead of providing one subscript enclosed in brackets, you supply two subscripts, each enclosed in its own set of brackets. You cannot put both subscripts in the same set of brackets, as you can do in Pascal.

The first subscript represents the row, and the second subscript represents the column. Remember that both subscripts are zero based. In Java, subscripts do not "wrap around" as they do in some other languages such as C. You cannot access scores[1][0] by using the notation scores[0][3]. That's because, in reality, you are accessing an individual array variable, as shown in the illustration below. 

Shows the declaration and actual memory values of a 2D array

Initializing 2D Arrays

You can initialize a 2D array by using a loop and storing values in each element, just as you can with a single-dimensional array. Of course, when accessing 2D arrays, you'll usually use a pair of nested for loops with indexes for the row and column.

Just as with 1D arrays, you can create and initialize a 2D array in one statement by providing a list of initial values in an initializer list. When you do this, you supply a separate initializer list for each of the subarrays. Each of these subarray initializers is enclosed in its own set of braces, and separated from the others by commas.

Here's an example that creates a 4 x 3 array of Strings that imitates the layout of a standard numeric keypad:

String[][] keyCaps = {
    { "7", "8", "9" },
    { "4", "5", "6" },
    { "1", "2", "3" },
    { "0", "C", "." }};

When you use automatic initialization like this, you must remember to match the number of brackets and initializers. If you have only a single bracket after String[] your program won't compile.

Back to Top

Processing 2D Arrays

As previously mentioned, you'll normally process a 2D array by using a pair of nested for loops with indices for the rows and columns. This is pretty straightforward.

Here's some code that processes the array keyCaps, from the last section, to create a set of Buttons:

for (int row = 0; row < 4; row++)
  for (int col = 0; col < 3; col++)
    add(new Button(keyCaps[row][col]));

Of course, if you want to avoid hard-coding the sizes of the rows and columns, Java allows you to make a perfectly generic traveral loop by using each array's length field like this (assuming an array named a):

for (int r = 0; r < a.length; r++)
  for (int c = 0; c < a[r].length; c++)
    // Process a[r][c] here

Notice that each row in a 2D array can be treated as a 1D array in its own right. Thus for the inner loop in this example, [when processing the columns], we could test against a[r].length, because each subarray has its own length field.

Here is the applet NumPad.java which uses this code to create a simple numeric keypad.

2D Arrays and Methods

The way that Java 2D arrays are implemented makes it very easy to write methods which take 2D arrays as arguments. You just have to remember to declare the formal arguments using two brackets instead of one.

Here's an example of a method that takes a 2D array of double and returns the sum of all the numbers.
The sum2D() Method
double sum2D(double[][] ar)
{
  double sum = 0.0;

  for (int r=0; r < ar.length; r++)
    for (int c=0; c < ar[r].length; c++)
      sum += ar[r][c];

  return sum;
}

Back to Top

Returning 2D Arrays

Just as with 1D arrays, you can return 2D arrays from your methods. If, for instance, you're certain that every row in your 2D array has the same number of elements, you could return a 2D array containing the sum of each row and column like this:

The sum2DAR() Method
double[][] sum2DAR(double[][] ar)
{
  double[][] ans;
  ans[0] = new double[ar.length]; // rows
  ans[1] = new double[ar[0].length];

  for (int r=0; r < ar.length; r++)
  {
    for (int c=0; c < ar[r].length; c++)
    { 
      // Add each row total;
      ans[0][r] += ar[r][c];

      // Sum of each column
      ans[1][c] += ar[r][c];
    }
  }
  return ans;
  // ans[0] contains sum of each row
  // ans[1] contains sum of each col
}

Back to Top

Ragged Arrays

The array returned from sum2DAR() is called a ragged array, because the two 1D arrays ans[0] and ans[1] normally will have different lengths. If you pass a 2D array that has 20 columns and only 5 rows, then the returned array will have 5 elements in the the first array ans[0] and 20 elements in the second array ans[1].

To create a ragged array, you have to initialize each row of the 2D array independently, as is done inside sum2DAR() with this code:

double[][] ans;
ans[0] = new double[ar.length];
ans[1] = new double[ar[0].length];

Something to Talk About

Are you a 2D master? Let's see. How would you create a 5-column, 7-row array of int, and then use a loop to initialize each element in the array to the product of its row subscript plus 5 and its column subscript minus 3.

Please continue to the next section of this lesson.

 

Back to Top

 

Content Developed by Stephen Gilbert, Licensed under a Creative Commons License
Published by the Sofia Open Content Initiative
© 2004 Foothill-De Anza Community College District &The William and Flora Hewlett Foundation