Aqua Phoenix
     >>  Lectures >>  Java 3  
 

Navigator
   
 
       
   

3.1 Arrays

Arrays in Java are also objects, but they have some special notations and syntax conventions. These conventions are comparable to C, and allow for easier and more efficient handling of Arrays.

Arrays are declared with square brackets []:

int[] myNumbers;
Student students[];
Both notations, whether the brackets appear after the data type or after the array name, are allowed. The above declarations merely reserve an address for the reference for the array. To reserve memory space for the array's content, the array needs to be defined with some size:

myNumbers = new int[10];
students = new Student[60];
Declaration and definition can be combined, as was the case for primitive data types:

int[] myNumbers = new int[10];
Student students[] = new Student[60];
By default, numbers in an array of primitive data type are initialized to zero, and any objects are initialized to null. Hence, in the above examples,
  • the array myNumbers is initially filled with zero's
  • the array students is initially filled with null's. This means that the individual elements in the array still need to be defined separately. The declaration and definition above only sets aside memory space for the references to the potential Student objects.

Arrays can be defined as constants, but only when declaration and definition are performed at the same time:

int[] fibonacci10 = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 };
Double or higher-dimensional arrays are declared in a similar fashion:

int[][] doubleArray = { { 1, 2, 3}, {4, 5, 6} };
Student[][] students = new Student [6][20];
Dimensions in double or higher-dimensional arrays need not be defined all at once. It is perfectly legal to define the first dimension at a different point in time than the other dimension(s):

int[][] doubleArray = new int[80][];
In a later step, the second dimension can be defined:

...
doubleArray[8] = new int[45];
...
The implications of this type of array handling are many-folded, and are interesting to mention and understand:

  • Unlike in C, Matlab, or other languages, double arrays are not really double-arrays in the sense of rectangular matrices. They are instead a collection of other arrays, which may or may not be equally sized.

Figure 3.1: 2-dimensional array
  • The amount of memory allocated to the entire N-dimensional array can change dynamically, as the 1-D array objects pointed to by the parent array can change and be defined freely at any point.
  • Because of the dynamic allocation of memory, it is unlikely that the allocated memory is contiguous, and thus N-dimensional arrays are often fragmented in memory.
  • To access an element in an N-dimensional array, one in fact accesses N number of objects, making these array structures inefficient. In a 2-D array, for examples, the first pair of square brackets accesses the first array object and the second pair accesses another array object. The typical underlying simple math to access a memory offset is thereby convoluted by object referencing.

To access array elements, the same square brackets are used. Array indexing in Java is zero-based, i.e. counting elements starts at zero.

1-D:

  • myNumbers[0] (1st element)
  • myNumbers[3] (4th element)

2-D:

  • students[0][5] (1st row, 6th column)
  • students[2] (3rd sub-array)

One of the most important and most used instance variables for arrays is called length . It is a protected variable and cannot be changed, but can be accessed to find the length of an array. length is accessed as follows:

myNumbers.length
length holds the number of elements in the array, and is thus one larger than the last index. A typical loop to iterate over the elements of an array is as follows:

for (int i = 0; i < myNumbers.length; i++) {
  ...
}
Interestingly enough, the full scope of encapsulation has not been used here. As opposed to providing a method by the name of getLength(), the instance variable length is used directly. This is not a violation of any sort, and in fact allows for more efficient processing of arrays. Because accessing the length attribute of an array is a very common operation, and calling a method is overly expensive, referencing the instance variable is a fast alternative.

When accessing an element outside of the boundaries of an array, and ArrayIndexOutOfBoundsException is thrown. This is similar to a warning, and can be handled in order to ensure that the remainder of the code executes properly. Unlike in C, where out-of-bounds indexing may result in unexpected data or segmentation faults, Java checks for illegal indexing. This is mostly due to the fact that arrays are objects, and are not direct mappings to memory addresses.