12. Arrays and Array Processing

12.2. One-Dimensional Arrays

An array is considered a data structure. A data structure is an organized collection of data. In an array, data are arranged in a linear or sequen-

 

tial structure, with one element following another. When referencing ele- ments in an array, we refer to the position of the particular element within the array. For example, if the array is named arr, then the elements are named arr[0], arr[1], arr[2], ... arr[n-1], where n gives the number of elements in the array. This naming also reflects the fact that the array’s data are contained in storage locations that are next to each other. In Java, as in C, C++, and some other programming languages, the

first element of an array has index 0. (This is the same convention we usedZero indexing

for Strings.)

 

 

Array nameSubscripts


Figure 9.1: An array of 15 integers named arr.

 

012345678910 11 12 13 14


Contents

 

 

arr

 

 

Figure 9.1 shows an array named arr that contains 15 int elements.

The syntax for referring to elements of an array is

 

where arrayname is the name of the array—any valid identifier will do— and subscript is the position of the element within the array. As Fig- ure 9.1 shows, the first element in the array has subscript 0, the second has subscript 1, and so on.

A subscript is an integer quantity contained in square brackets that is used to identify an array element. An subscript must be either an integer

value or an integer expression. Using Figure 9.1 to illustrate an example, Subscript expressions

suppose that j and k are integer variables equaling 5 and 7, respectively. Each of the following then would be valid references to elements of the array arr:

,,

 

 

 

J

These examples show that when an expression, such as j + k, is used as a subscript, it is evaluated (to 12 in this case) before the reference is made.

It is a syntax error to use a noninteger type as an array subscript. Each of the following expressions would be invalid:

 

 

 

\J

For a given array, a valid array subscript must be in the range 0 ... N-1, where N is the number of elements in the array or it is considered out-of- bounds. An out-of-bounds subscript creates a run-time error—that is, an error that occurs when the program is running—rather than a syntax error,

 

which can be detected when the program is compiled. For the array arr, each of the following expressions contain out-of-bounds subscripts:

,,

 

 

 

J

Each of these references would lead to an IndexOutOfBoundsException. (Exceptions are covered in detail in Chapter 10.)

 

 

 

 

 

 

 

Are arrays objects?

 

 

 

 

 

 

 

 

 

 

 

 

Components and elements


Declaring and Creating Arrays

For the most part, arrays in Java are treated as objects. Like objects, they are instantiated with the new operator and they have instance variables (for example, length). Like variables for objects, array variables are con- sidered reference variables. When arrays are used as parameters, a refer- ence to the array is passed rather than a copy of the entire array. The primary difference between arrays and full-fledged objects is that arrays aren’t defined in terms of an Array class. Thus, arrays don’t fit into Java’s Object hierarchy. They don’t inherit any properties from Object and they cannot be subclassed.

You can think of an array as a container that contains a number of vari- ables. As we’ve seen, the variables contained in an array object are not referenced by name but by their relative position in the array. The vari- ables are called components. If an array object has N components, then we say that the array length is N. Each of the components of the array has the same type, which is called the array’s component type. An empty array is one that contains zero variables.

A one-dimensional array has components that are called the array’s elements. Their type is the array’s element type. An array’s elements may be of any type, including primitive and reference types. This means you can have arrays of int, char, boolean, String, Object, Image, TextField, TwoPlayerGame, and so on.

When declaring a one-dimensional array, you have to indicate both the array’s element type and its length. Just as in declaring and creating other kinds of objects, creating an array object requires that we create both a

 

name for the array and then the array itself. The following statements create the array shown in Figure 9.1:

 

 

\J

These two steps can be combined into a single statement as follows:

,,

 

J

In this example, the array’s element type is int and its length is 15, which is fixed and cannot be changed. This means that the array contains 15 variables of type int, which will be referred to as arr[0], arr[1],

...arr[14].

Array Allocation

Creating the array in Figure 9.1 means allocating 15 storage locations that Allocating memory

can store integers. Note that one difference between declaring an array and declaring some other kind of object is that square brackets ([]) are used to declare an array type. The brackets can be attached either to the array’s name or to its type, as in the following examples:

,,

 

J

The following example creates an array of five Strings and then uses a for loop to assign the strings "hello1", "hello2", "hello3", "hello4", and "hello5" to the five array locations:

,,

 

 

 

 

J

Note that the expression k < strarr.length specifies the loop bound. Every array has a length instance variable, which refers to the number of elements contained in the array. As we mentioned, arrays, like Strings,

are zero indexed, so the last element of the array is always given by its length vs. length()

length-1. However, length is an instance variable for arrays, whereas length() is an instance method for Strings. Therefore, it would be a syntax error in this example to refer to strarr.length().

In the example, we first use the new operator to create strarr, an array of type String of length five. We then use a String constructor to create

 

Figure 9.2: Creating an array of five Strings involves six objects, because the array itself is a sepa- rate object. In (a), the array vari- able is declared. In (b), the ar- ray is instantiated, creating an ar- ray of five null references. In (c), the five Strings are created and assigned to the array.


(a)

 

 

 

 

(b)

 

 

 

 

 

 


strarr

 

 

strarr


 

 

 

 

 

 

 

 

 

 

 

strarr


 

String strarr[]; // Null array variable

 

 

 

// Creates an array of null String

// references. strarr=new String [5];

 

// Creates 5 Strings and

/ assigns them to the array

 

for (int k=0; k 6 strarr.length; k++) strarr[k]=new String();

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Arrays of objects

 

 

 

 

school


the five Strings that are stored in the array. It is important to realize that creating an array to store five Objects (as opposed to five primitive data elements) does not also create the Objects themselves that will be stored in the array.

When an array of objects is created, the array’s elements are references to those objects (Fig. 9.2). Their initial values, like all reference variables, are null. So to create and initialize the array strarr, we need to create six objects—the array itself, which will contain five Strings, and then the five Strings that are stored in strarr.

One more example will help underscore this point. The following state- ments create four new Objects, an array to store three Students plus the three Students themselves:

,,

 

 

 

 

 

J

The first statement creates an array named school to store three Students, and the next three statements create the individual Students and assign them to the array (Fig. 9.3). Thus, creating the array and initializing its elements require four new statements.

The following sequence of statements would lead to a null pointer

exception because the array’s elements have not been instantiated:

Figure 9.3: An array of Students.,,

 

J

 

In this case, students[0] is a null reference, thus causing the exception.

 

 

Now that we’ve assigned the three Students to the array, we can refer to them by means of subscripted references. A reference to the Student named “Socrates” is now school[0], and a reference to the Student named “Plato” is school[1]. In other words, to refer to the three indi- vidual students we must refer to their locations within school. Of course, we can also use variables, such as loop counters, to refer to a Student’s location within school. The following for loop invokes each Student’s getState() method to print out its current state:

,,

 

Jschool

What if the three Students already existed before the array was cre- ated? In that case, we could just assign their references to the array elements, as in the following example:

,


 

 

 

 

 

 

 

 

 

 

 

student3

 

 

 

 

 

stud

 

 

Jstude

In this case, each of the three Student objects can be referenced by two

different references—its variable identifier (such as student1) and its ar-

 

ray location (such as school[0]). For arrays of objects, Java stores just the reference to the object in the array itself, rather than the entire object. This conserves memory, since references require only 4 bytes each whereas each object may require hundreds of bytes (Fig. 9.4).

When an array of N elements is created, the compiler allocates storage for N variables of the element’s type. In the case of arr that we discussed earlier, the compiler would allocate storage for 15 ints—60 contiguous bytes of storage, because each int requires 4 bytes (32 bits) of storage. If we declare an array of 20 doubles,


Figure 9.4: Arrays of objects store references to the objects, not the objects themselves.

 

,,

 

 

 

the compiler will allocate 160 bytes of storage—20 variables of 8 bytes (64 bits) each. In the case of the Student examples and String exam- ples, because these are objects (not primitive types), the compiler will al- locate space for N addresses, where N is the length of the array and where each address requires 4 bytes.


J

 

How much memory?

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Default initialization

 

 

Array initializer


SELF-STUDY EXERCISE

EXERCISE 9.1 How much space (in bytes) would be allocated for each of the following?

 

int a[] = new int[5];

double b[] = new double[10];

char c[] = new char[30];

String s[] = new String[10];

Student p[] = new Student[5];

Initializing Arrays

Array elements are automatically initialized to default values that depend on the element type: Boolean elements are initialized to false, and inte- ger and real types are initialized to 0. Reference types—that is, arrays of objects—are initialized to null.

Arrays can also be assigned initial values when they are created, al-

though this is feasible only for relatively small arrays. An array initializer is written as a list of expressions separated by commas and enclosed by braces. For example, we can declare and initialize the array shown in Figure 9.1 with the following statement:

,,

 

 

J

Similarly, to create and initialize an array of Strings, we can use the following statement:

,,

 

 

 

 

 

 

 

 

 

Array assignment


J

This example creates and stores four Strings in the array. Subsequently, to refer to “hello”, we would use the reference strings[0], and to refer to “love”, we would use the reference strings[3]. Note in these exam- ples that when an array declaration contains an initializer, it is not neces- sary to use new and it is not necessary to specify the number of elements in the array. The number of elements is determined from the number of values in the initializer list.

Assigning and Using Array Values

Array elements can be used in the same way as other variables. The only difference, of course, is that references to the elements are subscripted. For example, the following assignment statements assign values to the elements of two arrays, named arr and strings:

 

,,

 

 

 

 

J

 

SECTION 9.3 Simple Array Examples401

The following loop assigns the first 15 squares—1, 4, 9to the

array arr:

,,

 

J

The following loop prints the values of the array arr:

,,

 

J

 

SELF-STUDY EXERCISES

EXERCISE 9.2Declare an array named farr that contains ten floats initialized to the values 1.0, 2.0, ..., 10.0.

EXERCISE 9.3Write an expression that prints the first element of farr.

EXERCISE 9.4Write an assignment statement that assigns 100.0 to the last element in farr.

EXERCISE 9.5Write a loop to print all of the elements of farr.