Section 7.1
Creating and Using Arrays

WHEN A NUMBER OF DATA ITEMS are chunked together into a unit, the result is a data structure. Data structures can be quite complicated, but in many cases, a data structure consists simply of a sequence of data items. Data structures of this simple variety can be either arrays or records.

The term "record" is not used in Java. A record is essentially the same as a Java object that has instance variables only, but no instance methods. Some other languages, which do not support objects in general, nevertheless do support records. The data items in a record -- in Java, its instance variables -- are called the fields of the record. Each item is referred to using a field name. In Java, field names are just the names of the instance variables. The distinguishing characteristics of a record are that the data items in the record are referred to by name and that different fields in a record are allowed to be of different types. For example, if the class Person is defined as:

      class Person {
         String name;
         int id_number;
         Date birthday;
         int age;

then an object of class Person could be considered to be a record with four fields. The field names are name, id_number, birthday, and age. Note that the fields are of various types: String, int, and Date.

Because records are just a special type of object, I will not discuss them further.

Like a record, an array is just a sequence of items. However, where items in a record are referred to by name, the items in an array are numbered, and individual items are referred to by their position number. Furthermore, all the items in an array must be of the same type. So we could define an array as a numbered sequence of items, which are all of the same type. The number of items in an array is called the length of the array. The position number of an item in an array is called the index of that item. The type of the individual elements in an array is called the base type of the array.

In Java, items in an array are always numbered starting from zero. That is, the index of the first item in the array is zero. If the length of the array is N, then the index of the last item in the array is N-1. Once an array has been created, its length cannot be changed.

Java arrays are objects. This has several consequences. Arrays are created using the new operator. No variable can ever hold an array; a variable can only refer to an array. Any variable that can refer to an array can also hold the value null, meaning that it doesn't at the moment refer to anything. Like any object, an array belongs to a class, which like all classes is a subclass of the class Object.

Nevertheless, even though arrays are objects, there are differences between arrays and other types of objects, and there are a number of special language features in Java for creating and using arrays.

Suppose that A is a variable that refers to an array. Then the item at index k in A is referred to as A[k]. The first item is A[0], the second is A[1], and so forth. "A[k]" can be used just like a variable. You can assign values to it, you can use it in expressions, and you can pass it as a parameter to subroutines. All of this will be discussed in more detail below. For now, just keep in mind the syntax

array-variable [ integer-expression ]

for referring to an item in an array.

Although every array is a member of some class, array classes never have to be defined. Once a type exists, the corresponding array class exists automatically. If the name of the type is BaseType, then the name of the associated array class is BaseType[]. That is, an object belonging to the class BaseType[] is an array of items, where each item is a value of type BaseType. The brackets, "[]", are meant to recall the syntax for referring to the individual items in the array. "BaseType[]" can be read as "array of BaseType."

The base type of an array can be any legal Java type, that is, it can be a primitive type, an interface, or a class. From the primitive type int, the array type int[] is derived. Each item in an array of type int[] is a value of type int. From a class named Shape, the array type Shape[] is derived. Each item in an array of type Shape[] is a value of type class, which can be either null or a reference to an object belonging to the class Shape. (It might be worth mentioning here that if ClassA is a subclass of ClassB, then ClassA[] is automatically a subclass of ClassB[].)

Let's try to get a little more concrete about all this, using arrays of integers as an example. Since int[] is a class, it can be used to declare variables. For example,

      int[] list;

creates a variable named list of type int[]. This variable is capable of referring to an array of ints, but initially its value is null. The new operator can be used to create a new array object, which can then be assigned to list. The syntax for using new with arrays is different from the syntax you learned previously for regular classes. As an example,

      list = new int[5];

creates an array of five integers. More generally, "new BaseType[N]" creates an array belonging to the class BaseType[]. The value N in brackets gives the length of the array, that is, the number of items that it holds. Note that the array "knows" how long it is. The length of the array is something like an instance variable of the array object, and in fact, the length of the array list can be referred to as list.length. (However, you are not allowed to change the value of list.length, so its not really a regular instance variable.) The situation produced by the statement "list = new int[5];" can be pictured like this:

(Illustration of an array of ints)

Note that the newly created array of integers is automatically filled with zeros. In Java, a newly created array is always filled with a known, default value.

The items in list are referred to a list[0], list[1], list[2], list[3], and list[4]. (Note that the index for the last item is one less than list.length.) However, array references can be much more general than this. The brackets in an array reference can contain any expression whose value is an integer. For example if indx is a variable of type int, then list[indx] and list[2*indx+7] are syntactically correct references to items in the array list. And the following loop would print all the integers in the array, list, to standard output:

        for (int i = 0; i < list.length; i++) {
           System.out.println( list[i] );

The first time through the loop, i is 0, and list[i] refers to list[0]. The second time through, i is 1, and list[i] refers to list[1]. The loop ends after printing list[4], when i becomes equal to 5 and the continuation condition "i<list.length", is no longer true. This is a typical example of using a loop to process an array. I'll discuss more examples of array processing in the next section.

If you think for a moment about what the computer will do when it encounters an expression such as "list[k]" while it is executing a program, you'll see that there are two things that can go wrong. The expression is an attempt to access some specific element in the array referred to by the variable list. But suppose that the value of list is null. If that is the case, then list doesn't even refer to an array, and so the attempt to use the array item list[k] is an error. This is an example of a "null pointer error." Even if list does refer to an array, it's possible that the value of k is outside the legal range of indices for that array. This will happen if k < 0 or if k >= list.length. In that case, once again, there is no such thing as list[k]. This is called an "array index out of bounds" error. When you use arrays in a program, you should be careful not to commit either of these errors.

For an array variable, just as for any variable, you can declare the variable and initialize it in a single step. For example,

int[] list = new int[5];

The new array is filled with the default value appropriate for the base type of the array -- zero for int and null for class types, for example. However, Java also provides a way to initialize an array variable with a new array filled with a specified list of values. This is done with an array initializer. For example,

int[] list = { 1, 4, 9, 16, 25, 36, 49 };

creates a new array containing the seven values 1, 4, 9, 16, 25, 36, and 49, and sets list to refer to that new array. The value of list[0] will be 1, the value of list[1] will be 2, and so forth. The length of list is seven, since seven values are provided in the initializer.

An array initializer takes the form of an array of values, separated by commas and enclosed between braces. The length of the array does not have to be specified, because it is implicit in the list of values. The items in an array initializer don't have to be constants. They can be variables or expressions, provided that their values are of the appropriate type. For example, the following declaration creates an array of eight Colors. Some of the colors are given by expressions of the form "new Color(r,g,b)":

        Color[] palette =
                     new Color(0,180,0),  // dark green
                     new Color(180,180,255),  // light blue

One final note: For historical reasons, the declaration

int[] list;

can also be written as

int list[];

which is a syntax used in the languages C and C++. However, this alternative syntax does not really make much sense in the context of Java, and it is probably best avoided. After all, the intent is to declare a variable of a certain type, and the name of that type is "int[]". It makes sense to follow the "type-name variable-name;" syntax for such declarations.

[ Next Section | Previous Chapter | Chapter Index | Main Index ]