Examples Using Arrays
This section presents several examples that demonstrate declaring arrays, creating arrays, initializing arrays and manipulating array elements.
Creating and Initializing an Array
The application of Fig. 7.2 uses keyword new to create an array of 10 int elements, which are initially zero (the default for int variables).
Figure 7.2. Initializing the elements of an array to default values of zero.
(This item is displayed on page 290 in the print version)
1 // Fig. 7.2: InitArray.java 2 // Creating an array. 3 4 public class InitArray 5 { 6 public static void main( String args[] ) 7 { 8 int array[]; // declare array named array 9 10 array = new int[ 10 ]; // create the space for array 11 12 System.out.printf( "%s%8s ", "Index", "Value" ); // column headings 13 14 // output each array element's value 15 for ( int counter = 0; counter < array.length; counter++ ) 16 System.out.printf( "%5d%8d ", counter, array[ counter ] ); 17 } // end main 18 } // end class InitArray
|
Line 8 declares arraya reference capable of referring to an array of int elements. Line 10 creates the array object and assigns its reference to variable array. Line 12 outputs the column headings. The first column contains the index (09) of each array element, and the second column contains the default value (0) of each array element.
The for statement in lines 1516 outputs the index number (represented by counter) and value of each array element (represented by array[ counter ]). Note that the loop control variable counter is initially 0index values start at 0, so using zero-based counting allows the loop to access every element of the array. The for's loop-continuation condition uses the expression array. length (line 15) to determine the length of the array. In this example, the length of the array is 10, so the loop continues executing as long as the value of control variable counter is less than 10. The highest index value of a 10-element array is 9, so using the less-than operator in the loop-continuation condition guarantees that the loop does not attempt to access an element beyond the end of the array (i.e., during the final iteration of the loop, counter is 9). We will soon see what Java does when it encounters such an out-of-range index at execution time.
Using an Array Initializer
A program can create an array and initialize its elements with an array initializer, which is a comma-separated list of expressions (called an initializer list) enclosed in braces ({ and }). In this case, the array length is determined by the number of elements in the initializer list. For example, the declaration
int n[] = { 10, 20, 30, 40, 50 };
creates a five-element array with index values 0, 1, 2, 3 and 4. Element n[ 0 ] is initialized to 10, n[ 1 ] is initialized to 20, and so on. This declaration does not require new to create the array object. When the compiler encounters an array declaration that includes an initializer list, the compiler counts the number of initializers in the list to determine the size of the array, then sets up the appropriate new operation "behind the scenes."
The application in Fig. 7.3 initializes an integer array with 10 values (line 9) and displays the array in tabular format. The code for displaying the array elements (lines 1415) is identical to that in Fig. 7.2 (lines 1516).
Figure 7.3. Initializing the elements of an array with an array initializer.
1 // Fig. 7.3: InitArray.java 2 // Initializing the elements of an array with an array initializer. 3 4 public class InitArray 5 { 6 public static void main( String args[] ) 7 { 8 // initializer list specifies the value for each element 9 int array[] = { 32, 27, 64, 18, 95, 14, 90, 70, 60, 37 }; 10 11 System.out.printf( "%s%8s ", "Index", "Value" ); // column headings 12 13 // output each array element's value 14 for ( int counter = 0; counter < array.length; counter++ ) 15 System.out.printf( "%5d%8d ", counter, array[ counter ] ); 16 } // end main 17 } // end class InitArray
|
Calculating a Value to Store in Each Array Element
Some programs calculate the value stored in each array element. The application in Fig. 7.4 creates a 10-element array and assigns to each element one of the even integers from 2 to 20 (2, 4, 6, ..., 20). Then the application displays the array in tabular format. The for statement at lines 1213 calculates an array element's value by multiplying the current value of the for loop's control variable counter by 2, then adding 2.
Figure 7.4. Calculating values to be placed into elements of an array.
(This item is displayed on page 292 in the print version)
1 // Fig. 7.4: InitArray.java 2 // Calculating values to be placed into elements of an array. 3 4 public class InitArray 5 { 6 public static void main( String args[] ) 7 { 8 final int ARRAY_LENGTH = 10; // declare constant 9 int array[] = new int[ ARRAY_LENGTH ]; // create array 10 11 // calculate value for each array element 12 for ( int counter = 0; counter < array.length; counter++ ) 13 array[ counter ] = 2 + 2 * counter; 14 15 System.out.printf( "%s%8s ", "Index", "Value" ); // column headings 16 17 // output each array element's value 18 for ( int counter = 0; counter < array.length; counter++ ) 19 System.out.printf( "%5d%8d ", counter, array[ counter ] ); 20 } // end main 21 } // end class InitArray
|
Line 8 uses the modifier final to declare the constant variable ARRAY_LENGTH, whose value is 10. Constant variables (also known as final variables) must be initialized before they are used and cannot be modified thereafter. If an attempt is made to modify a final variable after it is initialized in its declaration (as in line 8), the compiler issues the error message
cannot assign a value to final variable variableName
If an attempt is made to access the value of a final variable before it is initialized, the compiler issues the error message
variable variableName might not have been initialized
Good Programming Practice 7.2
Constant variables also are called named constants or read-only variables. Such variables often make programs more readable than programs that use literal values (e.g., 10)a named constant such as ARRAY_LENGTH clearly indicates its purpose, whereas a literal value could have different meanings based on the context in which it is used. |
Common Programming Error 7.4
Assigning a value to a constant after the variable has been initialized is a compilation error. |
Common Programming Error 7.5
Attempting to use a constant before it is initialized is a compilation error. |
Summing the Elements of an Array
Often, the elements of an array represent a series of values to be used in a calculation. For example, if the elements of an array represent exam grades, a professor may wish to total the elements of the array and use that sum to calculate the class average for the exam. The examples using class GradeBook later in the chapter, namely Fig. 7.14 and Fig. 7.18, use this technique.
The application in Fig. 7.5 sums the values contained in a 10-element integer array. The program declares, creates and initializes the array at line 8. The for statement performs the calculations. [Note: The values supplied as array initializers are often read into a program rather than specified in an initializer list. For example, an application could input the values from a user or from a file on disk (as discussed in Chapter 14, Files and Streams). Reading the data into a program makes the program more reusable, because it can be used with different sets of data.]
Figure 7.5. Computing the sum of the elements of an array.
1 // Fig. 7.5: SumArray.java 2 // Computing the sum of the elements of an array. 3 4 public class SumArray 5 { 6 public static void main( String args[] ) 7 { 8 int array[] = { 87, 68, 94, 100, 83, 78, 85, 91, 76, 87 }; 9 int total = 0; 10 11 // add each element's value to total 12 for ( int counter = 0; counter < array.length; counter++ ) 13 total += array[ counter ]; 14 15 System.out.printf( "Total of array elements: %d ", total ); 16 } // end main 17 } // end class SumArray
|
Using Bar Charts to Display Array Data Graphically
Many programs present data to users in a graphical manner. For example, numeric values are often displayed as bars in a bar chart. In such a chart, longer bars represent proportionally larger numeric values. One simple way to display numeric data graphically is with a bar chart that shows each numeric value as a bar of asterisks (*).
Professors often like to examine the distribution of grades on an exam. A professor might graph the number of grades in each of several categories to visualize the grade distribution for the exam. Suppose the grades on an exam were 87, 68, 94, 100, 83, 78, 85, 91, 76 and 87. Note that there was one grade of 100, two grades in the 90s, four grades in the 80s, two grades in the 70s, one grade in the 60s and no grades below 60. Our next application (Fig. 7.6) stores this grade distribution data in an array of 11 elements, each corresponding to a category of grades. For example, array[ 0 ] indicates the number of grades in the range 09, array[ 7 ] indicates the number of grades in the range 7079 and array[ 10 ] indicates the number of 100 grades. The two versions of class GradeBook later in the chapter (Fig. 7.14 and Fig. 7.18) contain code that calculates these grade frequencies based on a set of grades. For now, we manually create the array by looking at the set of grades.
Figure 7.6. Bar chart printing program.
1 // Fig. 7.6: BarChart.java 2 // Bar chart printing program. 3 4 public class BarChart 5 { 6 public static void main( String args[] ) 7 { 8 int array[] = { 0, 0, 0, 0, 0, 0, 1, 2, 4, 2, 1 }; 9 10 System.out.println( "Grade distribution:" ); 11 12 // for each array element, output a bar of the chart 13 for ( int counter = 0; counter < array.length; counter++ ) 14 { 15 // output bar label ( "00-09: ", ..., "90-99: ", "100: " ) 16 if ( counter == 10 ) 17 System.out.printf( "%5d: ", 100 ); 18 else 19 System.out.printf( "%02d-%02d: ", 20 counter * 10, counter * 10 + 9 ); 21 22 // print bar of asterisks 23 for ( int stars = 0; stars < array[ counter ]; stars++ ) 24 System.out.print( "*" ); 25 26 System.out.println(); // start a new line of output 27 } // end outer for 28 } // end main 29 } // end class BarChart
|
The application reads the numbers from the array and graphs the information as a bar chart. The program displays each grade range followed by a bar of asterisks indicating the number of grades in that range. To label each bar, lines 1620 output a grade range (e.g., "70-79: ") based on the current value of counter. When counter is 10, line 17 outputs 100 with a field width of 5, followed by a colon and a space, to align the label "100: " with the other bar labels. The nested for statement (lines 2324) outputs the bars. Note the loop-continuation condition at line 23 (stars < array[ counter ]). Each time the program reaches the inner for, the loop counts from 0 up to array[ counter ], thus using a value in array to determine the number of asterisks to display. In this example, array[ 0 ]array[ 5 ] contain zeroes because no students received a grade below 60. Thus, the program displays no asterisks next to the first six grade ranges. Note that line 19 uses the format specifier %02d to output the numbers in a grade range. This specifier indicates that an int value should be formatted as a field of two digits. The 0 flag in the format specifier indicates that values with fewer digits than the field width (2) should begin with a leading 0.
Using the Elements of an Array as Counters
Sometimes, programs use counter variables to summarize data, such as the results of a survey. In Fig. 6.8, we used separate counters in our die-rolling program to track the number of occurrences of each side of a die as the program rolled the die 6000 times. An array version of the application in Fig. 6.8 is shown in Fig. 7.7.
Figure 7.7. Die-rolling program using arrays instead of switch.
1 // Fig. 7.7: RollDie.java 2 // Roll a six-sided die 6000 times. 3 import java.util.Random; 4 5 public class RollDie 6 { 7 public static void main( String args[] ) 8 { 9 Random randomNumbers = new Random(); // random number generator 10 int frequency[] = new int[ 7 ]; // array of frequency counters 11 12 // roll die 6000 times; use die value as frequency index 13 for ( int roll = 1; roll <= 6000; roll++ ) 14 ++frequency[ 1 + randomNumbers.nextInt( 6 ) ]; 15 16 System.out.printf( "%s%10s ", "Face", "Frequency" ); 17 18 // output each array element's value 19 for ( int face = 1; face < frequency.length; face++ ) 20 System.out.printf( "%4d%10d ", face, frequency[ face ] ); 21 } // end main 22 } // end class RollDie
|
Fig. 7.7 uses the array frequency (line 10) to count the occurrences of each side of the die. The single statement in line 14 of this program replaces lines 2346 of Fig. 6.8. Line 14 uses the random value to determine which frequency element to increment during each iteration of the loop. The calculation in line 14 produces random numbers from 1 to 6, so array frequency must be large enough to store six counters. However, we use a seven-element array in which we ignore frequency[ 0 ]it is more logical to have the face value 1 increment frequency[ 1 ] than frequency[ 0 ]. Thus, each face value is used as an index for array frequency. We also replaced lines 5052 from Fig. 6.8 by looping through array frequency to output the results (lines 1920).
Using Arrays to Analyze Survey Results
Our next example uses arrays to summarize the results of data collected in a survey:
Forty students were asked to rate the quality of the food in the student cafeteria on a scale of 1 to 10 (where 1 means awful and 10 means excellent). Place the 40 responses in an integer array, and summarize the results of the poll.
This is a typical array-processing application (see Fig. 7.8). We wish to summarize the number of responses of each type (i.e., 1 through 10). The array responses (lines 911) is a 40-element integer array of the students' responses to the survey. We use an 11-element array frequency (line 12) to count the number of occurrences of each response. Each element of the array is used as a counter for one of the survey responses and is initialized to zero by default. As in Fig. 7.7, we ignore frequency[ 0 ].
Figure 7.8. Poll analysis program.
(This item is displayed on pages 296 - 297 in the print version)
1 // Fig. 7.8: StudentPoll.java 2 // Poll analysis program. 3 4 public class StudentPoll 5 { 6 public static void main( String args[] ) 7 { 8 // array of survey responses 9 int responses[] = { 1, 2, 6, 4, 8, 5, 9, 7, 8, 10, 1, 6, 3, 8, 6, 10 10, 3, 8, 2, 7, 6, 5, 7, 6, 8, 6, 7, 5, 6, 6, 5, 6, 7, 5, 6, 11 4, 8, 6, 8, 10 }; 12 int frequency[] = new int[ 11 ]; // array of frequency counters 13 14 // for each answer, select responses element and use that value 15 // as frequency index to determine element to increment 16 for ( int answer = 0; answer < responses.length; answer++ ) 17 ++frequency[ responses[ answer ] ]; 18 19 System.out.printf( "%s%10s", "Rating", "Frequency" ); 20 21 // output each array element's value 22 for ( int rating = 1; rating < frequency.length; rating++ ) 23 System.out.printf( "%d%10d", rating, frequency[ rating ] ); 24 } // end main 25 } // end class StudentPoll
|
The for loop at lines 1617 takes the responses one at a time from array responses and increments one of the 10 counters in the frequency array (frequency[ 1 ] to frequency[ 10 ]). The key statement in the loop is line 17, which increments the appropriate frequency counter, depending on the value of responses[ answer ].
Let's consider several iterations of the for loop. When control variable answer is 0, the value of responses[ answer ] is the value of responses[ 0 ] (i.e., 1), so the program interprets ++frequency[ responses[ answer ] ] as
++frequency[ 1 ]
which increments the value in array element 1. To evaluate the expression, start with the value in the innermost set of square brackets (answer). Once you know answer's value (which is the value of the loop control variable in line 16), plug it into the expression and evaluate the next outer set of square brackets (i.e., responses[ answer ], which is a value selected from the responses array in lines 911). Then use the resulting value as the index for the frequency array to specify which counter to increment.
When answer is 1, responses[ answer ] is the value of responses[ 1 ] (2), so the program interprets ++frequency[ responses[ answer ] ] as
++frequency[ 2 ]
which increments array element 2.
When answer is 2, responses[ answer ] is the value of responses[ 2 ] (6), so the program interprets ++frequency[ responses[ answer ] ] as
++frequency[ 6 ]
which increments array element 6, and so on. Regardless of the number of responses processed in the survey, the program requires only an 11-element array (ignoring element zero) to summarize the results, because all the response values are between 1 and 10 and the index values for an 11-element array are 0 through 10.
If the data in the responses array had contained invalid values, such as 13, the program would have attempted to add 1 to frequency[ 13 ], which is outside the bounds of the array. Java disallows this. When a Java program executes, the JVM checks array indices to ensure that they are valid (i.e., they must be greater than or equal to 0 and less than the length of the array). If a program uses an invalid index, Java generates a so-called exception to indicate that an error occurred in the program at execution time. A control statement can be used to prevent such an "out-of-bounds" error from occurring. For example, the condition in a control statement could determine whether an index is valid before allowing it to be used in an array-access expression.
Error-Prevention Tip 7.1
An exception indicates that an error has occurred in a program. A programmer often can write code to recover from an exception and continue program execution, rather than abnormally terminating the program. When a program attempts to access an element outside the array bounds, an ArrayIndexOutOfBoundsException occurs. Exception handling is discussed in Chapter 13. |
Error-Prevention Tip 7.2
When writing code to loop through an array, ensure that the array index is always greater than or equal to 0 and less than the length of the array. The loop-continuation condition should prevent the accessing of elements outside this range. |