Java - Fondamenti di programmazione C. Thomas Wu Copyright © 2009 - The McGraw-Hill Companies srl P a r a g r a f o 10.5 presentazione 10.5 Q La rubrica (Address Book) uesto paragrafo tratta gli array bidimensionali, utili per rappresentare dati in forma tabellare. Ogni elemento in un array bidimensionale è individuato da due indici, uno individua la riga, l’altro la colonna. In realtà, Java non offre una struttura esplicita per realizzare array bidimensionali, che vengono di fatto implementati come array di array. PARAGRAFO 10.5 Java - Fondamenti di programmazione C. Thomas Wu Copyright © 2009 - The McGraw-Hill Companies srl 576 Chapter 10 Arrays and Collections 10.5 Two-Dimensional Arrays twodimensional array A table organized in rows and columns is a very effective means for communicating many different types of information. Figure 10.13 shows sample data displayed in a tabular format. In Java, we represent tables as two-dimensional arrays. The arrays we have discussed so far are one-dimensional arrays because they have only one index. In this section, we describe how two-dimensional arrays are used in Java. Let’s begin with an example. Consider the following table with four rows and five columns. The table contains the hourly rate of programmers based on their skill level. The rows (horizontal) represent the grade levels, and the columns (vertical) Distance Table (in miles) Los Angeles San Francisco San Jose San Diego Monterey Los Angeles — 600 500 150 450 San Francisco 600 — 100 750 150 San Jose 500 100 — 650 50 San Diego 150 750 650 — 600 Monterey 450 150 50 600 — Multiplication Table 4 5 6 1 2 3 1 1 2 3 4 5 6 7 8 9 2 2 4 6 8 10 12 14 16 18 3 3 6 9 12 15 18 21 24 27 4 4 8 12 16 20 24 28 32 36 5 5 10 15 20 25 30 35 40 45 6 6 12 18 24 30 36 42 48 54 7 7 14 21 28 35 42 49 56 63 8 8 16 24 32 40 48 56 64 72 9 9 18 27 36 45 54 63 72 81 7 8 Tuition Table Day Students Boarding Students Grades 1–6 $16,000.00 $28,000.00 Grades 7–8 $19,000.00 $31,000.00 Grades 9–12 $22,500.00 $34,500.00 Figure 10.13 Examples of information represented as tables. 9 Java - Fondamenti di programmazione C. Thomas Wu Copyright © 2009 - The McGraw-Hill Companies srl 10.5 Two-Dimensional Arrays 577 represent the steps within a grade level. Reading the table, we know a programmer with skill grade level 2, step 1 earns $36.50 per hour. Grade 0 1 2 3 0 1 Step 2 3 4 10.50 20.50 34.00 50.00 12.00 22.25 36.50 60.00 14.50 24.00 38.00 70.00 16.75 26.25 40.35 80.00 18.00 28.00 43.00 99.99 We declare the pay scale table as double[][] payScaleTable; or double payScaleTable[][]; and create the array as payScaleTable = new double[4][5]; The payScaleTable array is a two-dimensional array because two indices— one for the row and another for the column—are used to refer to an array element. For example, to refer to the element at the second column (column 1) of the third row (row 2), we say payScaleTable[2][1] Figure 10.14 illustrates how the two indices are used to access an array element of a two-dimensional array. Row # Column # payScaleTable[ 2 ][ 1 ] 0 1 2 0 1 2 36.50 3 Figure 10.14 Accessing an element of a two-dimensional array. 3 4 Java - Fondamenti di programmazione C. Thomas Wu Copyright © 2009 - The McGraw-Hill Companies srl 578 Chapter 10 Arrays and Collections Let’s go over some examples to see how the elements of two-dimensional arrays are manipulated. This code finds the average pay of the grade 2 programmers. double average, sum = 0.0; for (int j = 0; j < 5; j++) { sum += payScaleTable[2][j]; } average = sum / 5; The next example prints out the pay difference between the lowest and highest steps for each grade level. double difference; for (int i = 0; i < 4; i++) { difference = payScaleTable[i][4] - payScaleTable[i][0]; System.out.println("Pay difference at Grade Level " + i + " is " + difference); } This code adds $1.50 to every skill level. for (int i = 0; i < 4; i++) { for (int j = 0; j < 5; j++) { payScaleTable[i][j] += 1.50; } } In the previous examples, we used literal constants such as 5 and 4 to keep them simple. For real programs, we need to write a loop that will work for two-dimensional arrays of any size, not just with the one with four rows and five columns. We can use the length field of an array to write such a loop. Using the length field, we can rewrite the third example as for (int i = 0; i < payScaleTable.length; i++) { for (int j = 0; j < payScaleTable[i].length; j++) { payScaleTable[i][j] += 1.50; } } Do you notice a subtle difference in the code? Let’s examine the difference between the expressions payScaleTable.length and payScaleTable[i].length Java - Fondamenti di programmazione C. Thomas Wu Copyright © 2009 - The McGraw-Hill Companies srl 10.5 Two-Dimensional Arrays 579 First, there is actually no explicit structure called two-dimensional array in Java. We only have one-dimensional arrays in Java. However, we can have an array of arrays, and this is how the conceptual two-dimensional array is implemented in Java. The sample array creation payScaleTable = new double[4][5]; is really a shorthand for payScaleTable = new double[4][ ]; payScaleTable[0] payScaleTable[1] payScaleTable[2] payScaleTable[3] = = = = new new new new double[5]; double[5]; double[5]; double[5]; which is equivalent to payScaleTable = new double[4][ ]; for (int i = 0; i < 4; i++) { payScaleTable[i] = new double[5]; } Figure 10.15 shows the effect of executing the five statements. The expression payScaleTable.length refers to the length of the payScaleTable array itself. payScaleTable 0 1 payScaleTable.length == 4 2 3 And the expression payScaleTable[1].length refers to the length of an array stored at row 1 of payScaleTable. payScaleTable 0 0 1 2 3 4 1 2 3 payScaleTable[1].length == 5 Java - Fondamenti di programmazione C. Thomas Wu Copyright © 2009 - The McGraw-Hill Companies srl 580 Chapter 10 Arrays and Collections Executing... 1 Will result in... payScaleTable 0 1 payScaleTable = new double[4][ ]; 2 3 2 payScaleTable 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 payScaleTable[0] = new double[5]; 2 3 3 payScaleTable 0 1 payScaleTable[1] = new double[5]; 2 3 4 payScaleTable 0 1 payScaleTable[2] = new double[5]; 2 3 5 payScaleTable 0 1 payScaleTable[3] = new double[5]; 2 3 Figure 10.15 Executing the statements on the left in sequence will create the array of arrays shown on the right. Java - Fondamenti di programmazione C. Thomas Wu Copyright © 2009 - The McGraw-Hill Companies srl 10.5 Two-Dimensional Arrays 581 We call an array that is part of another a subarray. The payScaleTable has four subarrays of the same length. Since we allocate the subarrays individually, we can create subarrays of different lengths. The following code creates a triangular array whose subarray triangularArray[i] has length i. triangularArray = new double[4][ ]; for (int i = 0; i < 4; i++) triangularArray[i] = new double[i+1]; The resulting triangularArray looks like this: triangularArray 0 0 0 1 0 1 2 0 1 2 1 2 3 3 An array of arrays can be initialized at the time of declaration. The following declaration initializes the payScaleTable array: double[][] payScaleTable = { {10.50, 12.00, {20.50, 22.25, {34.00, 36.50, {50.00, 60.00, 14.50, 24.00, 38.00, 70.00, 16.75, 26.25, 40.35, 80.00, 18.00}, 28.00}, 43.00}, 99.99} }; Here’s the complete sample program: /* Chapter 10 Sample Program: Sample program for processing 2-D array of double. File: Ch10PayScaleTable.java */ class Ch10PayScaleTable { public static void main (String[] args) { double[][] payScaleTable = { {10.50, {20.50, {34.00, {50.00, 12.00, 22.25, 36.50, 60.00, 14.50, 24.00, 38.00, 70.00, 16.75, 26.25, 40.35, 80.00, 18.00}, 28.00}, 43.00}, 99.99} }; Java - Fondamenti di programmazione C. Thomas Wu Copyright © 2009 - The McGraw-Hill Companies srl 582 Chapter 10 Arrays and Collections //Find the average pay of level 2 employees double sum = 0.0, average; for (int j = 0; j < 5; j++) { sum += payScaleTable[2][j]; } average = sum / 5; System.out.println(" Average of Level 2 Employees: " + average ); System.out.println("\n"); //Display the pay difference at each grade level double difference; for (int i = 0; i < 4; i++) { difference = payScaleTable[i][4] - payScaleTable[i][0]; System.out.println("Pay difference at Grade Level " + i + " is " + difference); } //Print out the pay scale table System.out.println("\n"); for (int i = 0; i < payScaleTable.length; i++) { for (int j = 0; j < payScaleTable[i].length; j++) { System.out.print( payScaleTable[i][j] + " " ); } System.out.println(""); } //Increase the pay by 1.50 for every level/step //and display the resulting table System.out.println("\n"); for (int i = 0; i < payScaleTable.length; i++) { for (int j = 0; j < payScaleTable[i].length; j++) { payScaleTable[i][j] += 1.50; System.out.print(payScaleTable[i][j] + " } System.out.println(""); } } } "); Java - Fondamenti di programmazione C. Thomas Wu Copyright © 2009 - The McGraw-Hill Companies srl 10.6 Lists and Maps 583 We can nest for-each loops to process a two-dimensional array. Remember that the two-dimensional array is structurally an array of arrays (as illustrated in Figure 10.15), and the nested for-each loops will make this fact explict. To print out the pay scale table, for example, we write for (double[] row : payScaleTable) { for (double pay : row) { System.out.print(pay + " "); } System.out.println(""); } The outer loop iterates over the rows in the payScaleTable two-dimensional array. Each row is one-dimensional array of double, so the type is declared as double[]. And the inner loop iterates over the elements in each row. Notice that we cannot rewrite the other loop statements in the Ch10PayScaleTable program by using the for-each loop. There is no limit to the number of dimensions an array can have. We can declare three-dimensional, four-dimensional, and higher-dimensional arrays. However, arrays with a dimension higher than 2 are not frequently used in objectoriented languages. For example, data that were represented as a three-dimensional array in a non-object-oriented language can be represented more naturally as a onedimensional array of objects with each object containing an array or some other form of data structure (see Exercise 12 on page 615). 1. Write a code fragment to compute the average pay of the pays stored in the payScaleTable array. 2. Write a code fragment that finds the largest integer in this two-dimensional array. int[][] table = new int[10][10]; 3. What is an output from this code? int[][] table = new int[10][5]; System.out.println(table.length); System.out.println(table[4].length); 10.6 Lists and Maps array overflow Once an array is created, its capacity cannot be changed. For example, if we create an array of 20 elements, then we are limited to store at most 20 elements in using this array. If we need to add elements, then we have to create a new array. (Note: We will learn how to do this in Section 10.7.) We call the condition in which an array does not have any unused position left to add another element an array overflow.