Chapter7
7.1 Introduction
A single array variable can reference a large collection of data.
7.2 Array Basics
Once an array is created, its size is fixed. An array reference variable is used to
access the elements in an array using an index.
7.2.1 Declaring Array Variables
To use an array in a program, you must declare a variable to reference the array and specifythe array’s element type. Here is the syntax for declaring an array variable:
elementType[] arrayRefVar;
double[] myList;
7.2.2 Creating Arrays
Declaring an array variable, creating an array, and assigning the reference of the array to
the variable can be combined in one statement as:
elementType[] arrayRefVar = new elementType[arraySize];
or
elementType arrayRefVar[] = new elementType[arraySize];
Here is an example of such a statement:
double[] myList = new double[10];
arrayRefVar[index] = value;
For example, the following code initializes the array.
myList[0] = 5.6;
myList[1] = 4.5;
myList[2] = 3.3;
myList[3] = 13.2;
myList[4] = 4.0;
myList[5] = 34.33;
myList[6] = 34.0;
myList[7] = 45.45;
myList[8] = 99.993;
myList[9] = 11123;
Note
An array variable that appears to hold an array actually contains a reference to that array. Strictly speaking, an array variable and an array are different, but most of the time the distinction can be ignored. Thus it is all right to say, for simplicity, that myList is an array, instead of stating, at greater length, that myList is a variable that contains a reference to an array of ten double elements.
7.2.3 Array Size and Default Values
7.2.5 Array Initializers
double[] myList = {1.9, 2.9, 3.4, 3.5};
double[] myList = new double[4];
myList[0] = 1.9;
myList[1] = 2.9;
myList[2] = 3.4;
myList[3] = 3.5;
Caution
The new operator is not used in the array-initializer syntax. Using an array initializer, you have to declare, create, and initialize the array all in one statement. Splitting it would cause a syntax error. Thus, the next statement is wrong:
double[] myList;
myList = {1.9, 2.9, 3.4, 3.5};
7.2.6 Processing Arrays
The following are some examples of processing arrays.
- Initializing arrays with input values: The following loop initializes the array myList with user input values.
java.util.Scanner input = new java.util.Scanner(System.in);
System.out.print("Enter " + myList.length + " values: ");
for (int i = 0; i < myList.length; i++)
myList[i] = input.nextDouble();
- Initializing arrays with random values: The following loop initializes the array myList
with random values between 0.0 and 100.0, but less than 100.0.
for (int i = 0; i < myList.length; i++) {
myList[i] = Math.random() * 100;
}
- Displaying arrays: To print an array, you have to print each element in the array using a
loop like the following:
for (int i = 0; i < myList.length; i++) {
System.out.print(myList[i] + " ");
}
char[] city = {'D', 'a', 'l', 'l', 'a', 's'};
System.out.println(city);//Dallas
7.2.7 Foreach Loops
Java supports a convenient for loop, known as a foreach loop, which enables you to traverse the array sequentially without using an index variable. For example, the following code displays all the elements in the array myList:
for (double e: myList) {
System.out.println(e);
}
You can read the code as “for each element e in myList, do the following.” Note that the variable, e, must be declared as the same type as the elements in myList.
7.5 Copying Arrays
To copy the contents of one array into another, you have to copy the array’s individual
elements into the other array.
There are three ways to copy arrays:
■ Use a loop to copy individual elements one by one.
■ Use the static arraycopy method in the System class.The syntax for arraycopy is:
arraycopy(sourceArray, srcPos, targetArray, tarPos, length);
■ Use the clone method to copy arrays; this will be introduced in Chapter 13, Abstract
Classes and Interfaces
garbage collection
The array previously
referenced by list2 is no longer referenced; it becomes garbage, which will be automatically
collected by the Java Virtual Machine (this process is called garbage collection).
7.6 Passing Arrays to Methods
When passing an array to a method, the reference of the array is passed to the method.
Just as you can pass primitive type values to methods, you can also pass arrays to methods.
For example, the following method displays the elements in an int array:
public static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
pass-by-value && pass-by-sharing
There are important differences between passing the values of variables of primitive data types and passing arrays.
■ For an argument of a primitive type, the argument’s value is passed.
■ For an argument of an array type, the value of the argument is a reference to an array;
this reference value is passed to the method. Semantically, it can be best described as pass-by-sharing, that is, the array in the method is the same as the array being passed.
Thus, if you change the array in the method, you will see the change outside the method.
public class Test {
public static void main(String[] args) {
int x = 1; // x represents an int value
int[] y = new int[10]; // y represents an array of int values
m(x, y); // Invoke m with arguments x and y
System.out.println("x is " + x);
System.out.println("y[0] is " + y[0]);
}
public static void m(int number, int[] numbers) {
number = 1001; // Assign a new value to number
numbers[0] = 5555; // Assign a new value to numbers[0]
}
}
You may wonder why after m is invoked, x remains 1, but y[0] become 5555. This is because y and numbers, although they are independent variables, reference the same array, as illustrated in Figure 7.5. When m(x, y) is invoked, the values of x and y are passed to number and numbers. Since y contains the reference value to the array, numbers now contains the same reference value to the same array.
7.7 Returning an Array from a Method
When a method returns an array, the reference of the array is returned.
public static int[] reverse(int[] list) {
int[] result = new int[list.length];
for (int i = 0, j = result.length - 1;
i < list.length; i++, j--) {
result[j] = list[i];
}
return result;
}
A brute-force approach to count the occurrences of each letter might be as follows:
for (int i = 0; i < chars.length; i++)
if (chars[i] == 'a')
counts[0]++;
else if (chars[i] == 'b')
counts[1]++;
...
But a better solution is given in lines 51–52.
for (int i = 0; i < chars.length; i++)
counts[chars[i] - 'a']++;
7.9 Variable-Length Argument Lists
A variable number of arguments of the same type can be passed to a method and treated as an array.
7.10 Searching Arrays
If an array is sorted, binary search is more efficient than linear search for finding an
element in the array.
7.10.1 The Linear Search Approach
The linear search approach compares the key element key sequentially with each element in the array. It continues to do so until the key matches an element in the array or the array is exhausted without a match being found. If a match is made, the linear search returns the index of the element in the array that matches the key. If no match is found, the search returns -1.
7.10.2 The Binary Search Approach
Binary search is the other common search approach for a list of values. For binary search to work, the elements in the array must already be ordered. Assume that the array is in ascending order. The binary search first compares the key with the element in the middle of the array.
Consider the following three cases:
■ If the key is less than the middle element, you need to continue to search for the key only in the first half of the array.
■ If the key is equal to the middle element, the search ends with a match.
■ If the key is greater than the middle element, you need to continue to search for the key only in the second half of the array.
7.11 Sorting Arrays
Sorting, like searching, is a common task in computer programming. Many different algorithms have been developed for sorting. This section introduces an intuitive sorting algorithm: selection sort.
public class SelectionSort {
/** The method for sorting the numbers */
public static void selectionSort(double[] list) {
for (int i = 0; i < list.length - 1; i++) {
// Find the minimum in the list[i..list.length-1]
double currentMin = list[i];
int currentMinIndex = i;
for (int j = i + 1; j < list.length; j++) {
if (currentMin > list[j]) {
currentMin = list[j];
currentMinIndex = j;
}
}
// Swap list[i] with list[currentMinIndex] if necessary
if (currentMinIndex != i) {
list[currentMinIndex] = list[i];
list[i] = currentMin;
}
}
}
}
7.12 The Arrays Class
The java.util.Arrays class contains useful methods for common array operations such as sorting and searching
The java.util.Arrays class contains various static methods for sorting and searching arrays, comparing arrays, filling array elements, and returning a string representation of the array. These methods are overloaded for all primitive types.
7.13 Command-Line Arguments
The main method can receive string arguments from the command line.
Perhaps you have already noticed the unusual header for the main method, which has the parameter args of String[] type. It is clear that args is an array of strings. The main method is just like a regular method with a parameter. You can call a regular method by passing actual parameters. Can you pass arguments to main? Yes, of course you can. In the following examples, the main method in class TestMain is invoked by a method in A.
public class A {
public static void main(String[] args) {
String[] strings = {"New York","Boston", "Atlanta"};
TestMain.main(strings);
}
}
public class TestMain {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++)
System.out.println(args[i]);
}
}
7.13.1 Passing Strings to the main Method*
You can pass strings to a main method from the command line when you run the program. The following command line, for example, starts the program TestMain with three strings: arg0, arg1, and arg2:
java TestMain arg0 arg1 arg2
arg0, arg1, and arg2 are strings, but they don’t have to appear in double quotes on the command line. The strings are separated by a space. A string that contains a space must be enclosed in double quotes. Consider the following command line:
java TestMain "First num" alpha 53
It starts the program with three strings: First num, alpha, and 53. Since First num is a string, it is enclosed in double quotes. Note that 53 is actually treated as a string. You can use “53” instead of 53 in the command line.
When the main method is invoked, the Java interpreter creates an array to hold the command-line arguments and pass the array reference to args. For example, if you invoke a program with n arguments, the Java interpreter creates an array like this one:
args = new String[n];
The Java interpreter then passes args to invoke the main method.
Note
If you run the program with no strings passed, the array is created with new String[0]. In this case, the array is empty with length 0. args references to this empty array. Therefore, args is not null, but args.length is 0.
7.13.2 Case Study: Calculator*
Suppose you are to develop a program that performs arithmetic operations on integers. The program receives an expression in one string argument. The expression consists of an integer followed by an operator and another integer. For example, to add two integers, use this command:
java Calculator 2 + 3
The program will display the following output:
2 + 3 = 5
Here are the steps in the program:
- Use args.length to determine whether the expression has been provided as three
arguments in the command line. If not, terminate the program using System.exit(1). - Perform a binary arithmetic operation on the operands args[0] and args[2] using the
operator in args[1].
public class Calculator {
/** Main method */
public static void main(String[] args) {
// Check number of strings passed
if (args.length != 3) {
System.out.println(
"Usage: java Calculator operand1 operator operand2");
System.exit(0);
}
// The result of the operation
int result = 0;
// Determine the operator
switch (args[1].charAt(0)) {
case '+': result = Integer.parseInt(args[0]) +
Integer.parseInt(args[2]);
break;
case '-': result = Integer.parseInt(args[0]) -
Integer.parseInt(args[2]);
break;
case '.': result = Integer.parseInt(args[0]) *
Integer.parseInt(args[2]);
break;
case '/': result = Integer.parseInt(args[0]) /
Integer.parseInt(args[2]);
}
// Display result
System.out.println(args[0] + ' ' + args[1] + ' ' + args[2]
+ " = " + result);
}
}
Integer.parseInt(args[0]) (line 16) converts a digital string into an integer. The string must consist of digits. If not, the program will terminate abnormally. We used the . symbol for multiplication, not the common * symbol. The reason for this is that the * symbol refers to all the files in the current directory when it is used on a command line. The following program displays all the files in the current directory when issuing the
command java Test *:
public class Test {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++)
System.out.println(args[i]);
}
}
To circumvent this problem, we will have to use a different symbol for the multiplication operator.