Chapter 6: Arrays

Array Basics

  • An array is used to store a collection of data, but it often more useful to think of an array as a collection of variables of the same type.
  • Instead of declaring individual variables, such as num0, num1, …, and num99, you declare one array variable such as num and use num[0] , num[1], …, num[99] to represent individual variables.

Declaring Array Variables

  • To use an array in a program, you must declare a variable to reference the array, and you must specify the type of array the variables can reference.
  • Here is the syntax for declaring an array variable:

dataType[ ] arrayRefVar;double[ ] myList;//preferred style

dataType arrayRefVar[ ];double myList[ ];//not preferred style

Creating Arrays

  • Declaration of an array variable doesn’t allocate any space in memory for the array.
  • Only a storage location for the reference to an array is created.
  • If a variable doesn’t reference to an array, the value of the variable is null.
  • You cannot assign elements to an array unless it has already been created.
  • After an array variable is declared, you can create an array by using the new operator with the following syntax:

arrayRefVar = new dataType[arraySize];

  • This statement does two things:

1)It creates an array using new dataType[arraySize];

2)It assigns the reference of the newly created array to the variable arrayRefVar.

  • Declaring an array variable, creating an array, and assigning the reference of the array to the variable can be combined in one statement, as follows:

dataType[]arrayRefVar = new dataType[arraySize];or

dataType arrayRefVar [] = new dataType[arraySize];

double[] myList = new double[10];

  • This statement declares an array variable, myList, creates an array of ten elements of double type, and assigns its reference to myList.
  • Figure below illustrates an array with sample element values.


  • The array myList has ten elements of double type and int indices from 0 to 9.

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 between them can be ignored.
  • Thus, it is alright to say, for simplicity, that myListis an array, instead of stating, at greater length, that myList is a variable that contains a reference to an array of ten double elements.
  • When the distinction makes a subtle difference, the longer phrase should be used.

Array Size and Default values

  • When space for an array is allocated, the array size must be given, to specify the number of elements that can be stored in it.
  • The size of an array cannot be changed after the array is created.
  • Size can be obtained using arrayRefVar.length myList.length is 10.
  • When an array is created, its elements are assigned the default value of 0 for the numeric primitive data types, ‘\u000’ for char types, and false for Boolean types.

Array Indexed Variables

  • The array elements are accessed through the index.
  • Array indices are 0-based, they start from 0 to arrayRefVar.length-1.
  • Each element in the array is represented using the following syntax:

arrayRefVar[index];

  • The element myList[9] represents the last element in the array. Indices are from 0 to 9.
  • After an array is created, an indexed variable can be used in the same way as a regular variable. For example:

myList[2] = myList[0] + myList[1];//adds the values of the 1st and 2nd

elements into the 3rd one

  • The following loop assigns 0 to myList[0] 1 to myList[1] .. and 9 to myList[9]:

for (int i = 0; i < myList.length; i++)

myList[i] = i;

Array Initializers

  • Java has a shorthand notation, known as the array initializer that combines declaring an array, creating an array and initializing in one statement:

double[] myList = {1.9, 2.9, 3.4, 3.5};

  • This shorthand notation is equivalent to the following statements:

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. For example, the following is wrong:

double[] myList;

myList = {1.9, 2.9, 3.4, 3.5};

Processing Arrays

  • When processing array elements, you will often use a for loop. Here are the reasons why:

1)All of the elements in an array are of the same type. They are evenly processed in the same fashion by repeatedly using a loop.

2)Since the size of the array is known, it is natural to use afor loop.

  • Here are some examples of processing arrays:

1)Initializing arrays with random values  0.0 – 99.0

for (int i = 0; i < myList.length; i++)

myList[i] = Math.random() * 100;

2)Printing arrays by using a loop like the one shown below

for (int i = 0; i < myList.length; i++)

System.out.print(myList[i] + “ “);

Tip: for an array of the char[] type, it can be printed using one print statement.

char[] city = {‘D’, ‘a’, ‘l’,‘l’, ‘a’, ‘s’};

System.out.println(city);displays Dallas

3)Summing array elements by using variable named total to store the sum. Initially total is 0. Add each element in the array to total, usinga loop like this:

double total = 0;

for (int i = 0; i < myList.length; i++)

total += myList[i];

4)Finding the largest element, use a variable named max to store the largest element. To find the largest element in the arraymyList, compare each element in myList with max, and update max if the element is greater than max.

double max = myList[0];

for (int i = 0; i < myList.length; i++){

if (myList[i] > max)

max = myList[i];

}

5)Finding the smallest index of the largest element, used to locate the largest element in an array. If an array has more than one largest element, find the smallest index of such an element. Suppose the array myList is {1, 5, 3, 4, 5, 5}. The largest element is 5, and the smallest index for 5 is 1. Use a variable named max to store the largest element and a variable named indexOfMax is 0. Compare each element inmyList with max, and update max and indexOfMaxif the element is greater than max.

double max = myList[0];

int indexOfMax = 0;

for (int i = 0; i < myList.length; i++) {

if (myList[i] > max) {

max = myList[i];

indexOfMax = i;

}

}

foreach Loops

  • A foreach loop is an enhanced for loop, which enables you to traverse the complete array sequentially without using an index variable.
  • The following code displays all the elements in the arraymyList:

for (double element: myList) {

System.out.println(element);

}

  • You can read the code as “for each element in myList do the following.”
  • Note that the variable, element, must be declared the same type as the element inmyList.
  • You still have to use an index variable if you wish to traverse the array in a different order or change the elements in the array.

Example: Testing Arrays

  • The following program finds the largest number and counts its occurrences.

// TestArray.java: Count the occurrences of the largest number

import javax.swing.JOptionPane;

publicclass TestArray {

/** Main method */
publicstaticvoid main(String[] args) {

finalint TOTAL_NUMBERS = 6;
int[] numbers = newint[TOTAL_NUMBERS];

// Read all numbers
for (int i = 0; i < numbers.length; i++) {
String numString = JOptionPane.showInputDialog(
"Enter a number:");
// Convert string into integer
numbers[i] = Integer.parseInt(numString);
}

// Find the largest
int max = numbers[0];
for (int i = 1; i < numbers.length; i++) {
if(max < numbers[i])
max = numbers[i];
}

// Find the occurrence of the largest number
int count = 0;
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == max) count++;
}

// Prepare the result
String output = "The array is ";
for (int i = 0; i < numbers.length; i++) {
output += numbers[i] + " ";
}
output += "\nThe largest number is " + max;
output += "\nThe occurrence count of the largest number "
+ "is " + count;
// Display the result
JOptionPane.showMessageDialog(null, output);
}
}

  • The program declares and creates an array of six integers. It finds the largest number in the array, and displays the result.
  • To display the array, you need to display each element in the array using a loop.
  • Without using the numbers array, you would have to declare a variable for each number entered, b/c all the numbers are compared to the largest number to count its occurrences after it is found.

Caution

  • Accessing an array out of bound is a common programming error that throws a runtime error ArraIndexOutOfBoundsException. To avoid it, make sure that you don’t use an index beyond arrayRefVar.length-1.
  • Programmers often mistakenly reference the first element in an array with index 1, so that the index of the 10th element becomes 10. This is called theoff-by-one-error.

Example: Assigning Grades

  • Objective: read student scores, get the best score, and then assign grades based on the following scheme:

Grade is A if score is >= best–10;

Grade is B if score is >= best–20;

Grade is C if score is >= best–30;

Grade is D if score is >= best–40;

Grade is F otherwise.

  • The program prompts the user to enter the total number of students, then prompts the user to enter all of the scores, and concludes by displaying the grades.

// AssignGrade.java: Assign grade
import javax.swing.JOptionPane;
publicclass AssignGrade {
/** Main method */
publicstaticvoid main(String[] args) {
// Get number of students
String numOfStudentsString = JOptionPane.showInputDialog(
"Please enter number of students:");

// Convert string into integer
int numOfStudents = Integer.parseInt(numOfStudentsString);

int[] scores = new int[numOfStudents]; // Array scores
int best = 0; // The best score
char grade; // The grade
// Read scores and find the best score
for (int i = 0; i < scores.length; i++) {
String scoreString = JOptionPane.showInputDialog(

"Please enter a score:");
// Convert string into integer
scores[i] = Integer.parseInt(scoreString);
if(scores[i] > best)
best = scores[i];
}
// Declare and initialize output string
String output = "";
// Assign and display grades
for (int i = 0; i < scores.length; i++) {
if (scores[i] >= best - 10)
grade = 'A';
elseif (scores[i] >= best - 20)
grade = 'B';
elseif (scores[i] >= best - 30)
grade = 'C';
elseif (scores[i] >= best - 40)
grade = 'D';
else
grade = 'F';
output += "Student " + i + " score is " +
scores[i] + " and grade is " + grade + "\n";
}
// Display the result
JOptionPane.showMessageDialog(null, output);
}
}

  • The program declares scoresas an array of inttype in order to store the students’ scores after the user enters the number of students into numOfStudents.
  • The size of the array is set at runtime; it cannot be changed once the array is created.

Copying Arrays

  • Often, in a program, you need to duplicate an array or a part of an array. In such cases you could attempt to use the assignment statement (=), as follows:

list2 = list1;

  • This statement does not copy the contents of the array referenced by list1to list2, but merely copies the reference value from list1to list2. After this statement, list1and list2 reference to the same array, as shown below.
  • Before the assignment statement, list1and list2point to separate memory locations.
  • After the assignment, the reference of the list1array is passed to list2.


The array previously referenced by list2 is no longer referenced; it becomes garbage, which will be automatically collected by the Java Virtual Machine.

  • You can use assignment statements to copy primitive data type variables, but not arrays.
  • Assigning one array variable to another variable actually copies one reference to another and makes both variables point to the same memory location.
  • There are three ways to copy arrays:
  1. Use a loop to copy individual elements.
  2. Use the static arraycopy method in the System class.
  3. Use the clone method to copy arrays. “Introduced in chapter 9.”
  • You can write a loop to copy every element from the source array to the corresponding element in the largest array.
  • The following code, for instance, copiessourceArray totargetArray using a for loop:

int[] sourceArray = {2, 3, 1, 5, 10};

int[] targetArray = new int[sourceArray.length];

for (int i = 0; i < sourceArrays.length; i++)

targetArray[i] = sourceArray[i];

  • Another approach is to use arraycopy method in the java.lang.System class to copy arrays instead of using a loop. The syntax for arraycopy is shown below:

arraycopy(sourceArray, src_pos, targetArray, tar_pos, length);

  • The parameters src_pos and targetArray indicate the starting positions in sourceArray and targetArray, respectively.
  • The number of elements copied from sourceArray to targetArray is indicated by length.
  • For example, you can rewrite the loop using the following statement:

System.arraycopy(sourceArray, 0, targetArray, 0, sourceArray.length);

  • The arraycopy does not allocate memory space for the target array. The target array must have already been created with its memory space allocated.
  • After the copying takes place, targetArray and sourceArray have the same content but independent memory locations.

The arraycopy method requires five arguments:

public static

void arraycopy(Object source,

int srcIndex,

Object dest,

int destIndex,

int length,

The two Object arguments indicate the array to copy from and the array to copy to. The three integer arguments indicate the starting location in each the source and the destination array, and the number of elements to copy. The following figure illustrates how the copy takes place:

The following program, ArrayCopyDemo, uses arraycopy to copy some elements from the copyFrom array to the copyTo array.

Publicclass ArrayCopyDemo {
publicstaticvoid main(String[] args) {
char[] copyFrom = { ‘d’, ‘e’, ‘c’, ‘a’, ‘f’, ‘f’, ‘e’,
‘I’, ‘n’, ‘a’, ‘t’, ‘e’, ‘d’ };
char[] copyTo = newchar[7];
System.arraycopy(copyFrom, 2, copyTo, 0, 7);
System.out.println(new String(copyTo));
}
}

Output: caffein

  • The arraycopy method call in this example program begins the copy at element number 2 in the source array. Recall that array indices start at 0, so that the copy begins at the array element ‘c’.
  • The arraycopy method call puts the copied elements into the destination array beginning at the first element (element 0) in the destination array copyTo. The copy copies 7 elements: ‘c’, ‘a’, ‘f’, ‘f’, ‘e’, ‘I’, and ‘n’. Effectively, the arraycopy method takes the “caffein” out of “decaffeinated”, like this:

Note that the destination array must be allocated before you call arraycopy and must be large enough to contain the data being copied.

Summary of Arrays

  • An array is a fixed-length data structure that can contain multiple objects of the same type. An array can contain any type of object, including arrays. To declare an array, you use the type of object that the array can contain and brackets.
  • The length of the array must be specified when it is created. You can use the new operator to create an array, or you can use an array initializer. Once created, the size of the array cannot change. To get the length of the array, you use the length attribute.
  • An element within an array can be accessed by its index. Indices begin at 0 and end at the length of the array minus 1.
  • To copy an array, use the arraycopy method in the System class.

Passing Arrays to Methods

  • The following method displays the elements of an int array:

public static void printArray(int[] array) {

for (int i = 0; i < array.length; i++) {

System.out.print(array[i] + " ");

}

}

  • The following invokes the method to display 3, 1, 2, 6, 4, and 2.

int[] list = {3, 1, 2, 6, 4, 2};

printArray(list);

printArray(new int[]{3, 1, 2, 6, 4, 2});

  • The preceding statement creates an array using the following syntax:

New dataType[] {value0, value1, …, valuek};

  • There is no explicit reference variable for the array. Such an array is called an anonymous array.
  • Java uses pass by value to pass arguments to a method. There are important differences between passing the values of variables of primitive data types and passing arrays.
  • For anargument of a primitive type, the argument’s value is passed.
  • For an argument of an array type, the value of an argument contains a reference to an array;this reference is passed to the method.

publicclass Test {
publicstaticvoid main(String[] args) {
int x = 1; // x represents an int value
int[] y = newint[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]);
}
publicstaticvoidm(int number, int[] numbers) {
number = 1001; // Assign a new value to number
numbers[0] = 5555; // Assign a new value to numbers[0]
}
}

  • Result is:

x is 1
y[0] is 5555

  • This is because y and numbersreference to the same array, although y and numbersare independent variables.
  • When invoking m(x, y), the values of x and y are passed to number and numbers.
  • Since y contains the reference value to the array,numbersnow contains the same reference value to the same array.
  • The JVM stores the array in an area of memory called theheap, which is used for dynamic memory allocation where blocks of memory are allocated and freed in an arbitrary order.
  • The primitive type value in x is passed to number, and the reference value in y is passed to numbers.

Example: Passing Array Arguments

  • Write two methods for swapping elements in an array. The first method, named swap, fails to swap two int arguments. The second method, named swapFirstTwoInArray, successfully swaps the first two elements in the array argument.

publicclass TestPassArray {
/** Main method */
publicstaticvoid main(String[] args) {
int[] a = {1, 2};
// Swap elements using the swap method
System.out.println("Before invoking swap");
System.out.println("array is {" + a[0] + ", " + a[1] + "}");
swap(a[0], a[1]);
System.out.println("After invoking swap");
System.out.println("array is {" + a[0] + ", " + a[1] + "}");
// Swap elements using the swapFirstTwoInArray method
System.out.println("Before invoking swapFirstTwoInArray");
System.out.println("array is {" + a[0] + ", " + a[1] + "}");
swapFirstTwoInArray(a);
System.out.println("After invoking swapFirstTwoInArray");
System.out.println("array is {" + a[0] + ", " + a[1] + "}");
}
/** Swap two variables */
publicstaticvoid swap(int n1, int n2) {
int temp = n1;
n1 = n2;
n2 = temp;
}
/** Swap the first two elements in the array */
publicstaticvoidswapFirstTwoInArray(int[] array) {
int temp = array[0];
array[0] = array[1];
array[1] = temp;
}
}

Result:

Before invoking swap
array is {1, 2}
After invoking swap
array is {1, 2}
Before invoking swapFirstTwoInArray
array is {1, 2}
After invoking swapFirstTwoInArray
array is {2, 1}

  • The two elements are not swapped using the swapmethod.
  • The second method works. The two elements are actually swapped using the swapFirstTwoInArraymethod.
  • Since the parameters in the swapmethod are primitive type, the values of a[0]and a[1]are passed to n1 and n2inside the method when invoking swap(a[0], a[1]).
  • The memory locations for n1 and n2are independent of the ones for a[0]and a[1].
  • The contents of the array are not affected by this call.