Thursday, January 13, 2011

Learning Objects for Arrays in Java

Summary: These learning objects explain arrays in the Java program language. Arrays are a data structure for efficiently accessing a large number of components of the same type.







Learning Objects for Arrays

Concept An array is a sequence of elements of the same type; the type of the elements can be a primitive types such as int, or a predefined or user-defined class type. To access an element of an array, an index is given; this may be any expression of type int, including an integer literal or a variable.
The source code of these learning objects can be found in array.zip.
TABLE 1
LOTopicJava Files (.java)Prerequisites
"Array objects"Array objectsArray01A, B 
"Array initializers"Array initializersArray021
"Passing arrays as parameters"Passing arrays as parametersArray032
"Returning an array from a method"Returning an array from a methodArray042
"Array assignment can create garbage"Array assignment can create garbageArray054
"Two-dimensional arrays"Two-dimensional arraysArray063
"Arrays of arrays"Arrays of arraysArray076
"Ragged Arrays"Ragged arraysArray086
"Arrays of objects"Arrays of objectsArray093
The example used in LO 1 through LO 4 is to fill an array with a sequence of fibonacci numbers (0,1,1,2,3,5,8). The programs for LO 5 through LO 8 concern matrices. The program for LO 9 is explained there.

Array objects

Concept An array is created in three steps: first a variable of an array type is declared; then the array is allocated; finally, the elements of the array are given values. The syntax for accessing an array a is a[i], and the field a.length gives the length of the array, so that if we modify the program by changing the size of the array the rest of the program need not change.
Program: Array01A.java
// Learning Object Array01A
//    array objects
public class Array01A {
    public static void main(/*String[] args*/) {
        int[] fib;
        fib = new int[7];
        fib[0] = 0;
        fib[1] = 1;
        for (int i = 2; i < fib.length; i++)
            fib[i] = fib[i-1] + fib[i-2];
    }
}
The program creates an array in the three steps described above.
  • Initially, the variable fib of type integer array (denoted int[]) is allocated and contains the null value.
  • new fib[7] creates an array object with its seven fields having the default integer value zero; then the reference to the object is returned and stored in the variable fib.
  • The length field of the array is displayed above the cells for the elements.
  • for loop is used to assign values to each element of the array.
  • The thin white lines show the constants and expressions that are used as indices into the array.
  • Automatic dereferencing: Although expressions like fib[i-2] seem to indicate that fib is being indexed, fib contains a reference to an array; an implicit operation of dereferencing is carried out to obtain the array itself from the reference and the index [i-2] is then applied to that array.
Concept It is possible to combine the first two steps in creating an array: declaring the array field and allocating the array object.
Program: Array01B.java
// Learning Object Array01B
//    array objects
public class Array01B {
    private final static int SIZE = 7;
    public static void main(/*String[] args*/) {
        int[] fib = new int[SIZE];
        fib[0] = 0;
        fib[1] = 1;
        for (int i = 2; i < fib.length; i++)
            fib[i] = fib[i-1] + fib[i-2];
    }
}
This program combines the declaration of the array field with its allocator. We have used the constant SIZE to specify the size of the array; this makes it easier to modify the program; nevertheless, fib.length is still used in the executable statements.
  • Initially, the static variable SIZE is created in the constant area and given its value.
  • The execution of the program is as before.
Exercise Modify the program so that the fibonacci sequence appears in reverse order.

Array initializers

Concept An array object can be created implicitly by giving a list of values within braces.
Program: Array02.java
// Learning Object Array02
//   array initializers
public class Array02 {
    public static void main(/*String[] args*/) {
        int[] fib = {0, 1, 1, 2, 3, 5, 8};
    }
}
The program initializes an array with values of the fibonacci sequence.
  • Initially, the variable fib of type integer array (denoted int[]) is allocated.
  • As part of the same statement, the array object is created and its seven fields contain the values from the initializer.
  • Only then is the reference to the object returned and stored in the variable fib.
Exercise Can an element of an array initializer be the value of an expression containing variables previously declared? Modify this program accordingly and try to compile and run it. Explain what happens.

Passing arrays as parameters

Concept An array is an object. Since the array variable itself contains a reference, it can be passed as an actual paramter to a method and the reference is used to initialize the formal parameter.
Program: Array03.java
// Learning Object Array03
//    passing arrays as parameters
public class Array03 {
    static void reverse(int[] a) {
        int temp,j;
        for (int i = 0; i < a.length / 2; i++) {
            j = a.length-i-1;
            temp = a[i];
            a[i] = a[j];
            a[j] = temp;
        }
    }
 
    public static void main(/*String[] args*/) {
        int[] fib = {0, 1, 1, 2, 3, 5, 8};
        reverse(fib);
    }
}
This program passes an array as a parameter to a method that reverses the elements of the array.
  • Initially, the variable fib of type integer array is allocated. As part of the same statement, the array object is created with its seven fields having the values in the initializer; the reference to the object is returned and stored in the variable fib.
  • The array (that is, a reference to the array) is passed as a parameter to the method reverse. There are now two arrows pointing to the array: the reference from the mainmethod and the reference from the parameter a of the method reverse.
  • The method scans the first half of the array, exchanging each element with the corresponding one in the second half. Variables i and j contain the indices of the two elements that are exchanged.
  • Upon return from the method, the variable fib still contains a reference to the array, which has had its sequence of values reversed.
Exercise Instead of declaring the variable j outside the for-loop, declare it just inside the for-loop as follows:
int j = a.length-i-1;
Trace the execution and explain what happens.

Returning an array from a method

Concept An array can be allocated within a method. Although the variable containing the reference to the array is local to the method, the array itself is global and the reference can be returned from the method.
Program: Array04.java
// Learning Object Array04
//    returning an array from a method
public class Array04 {
    static int[] reverse(int[] a) {
        int[] b = new int[a.length];
        int j;
        for (int i = 0; i < a.length / 2; i++) {
            j = a.length-i-1;
            b[j] = a[i];
            b[i] = a[j];
        }
        return b;
    }
 
    public static void main(/*String[] args*/) {
        int[] fib = {0, 1, 1, 2, 3, 5, 8};
        int[] reversedFib = reverse(fib);
    }
}
This program passes an array as a parameter to a method that reverses the elements of the array. The array is reversed into a new array b that is allocated in the method reverse. It is then returned to the main method and assigned to reversedFib, a different variable of the same array type int[].
  • Initially, the variable fib of type integer array is allocated. As part of the same statement, the array object is created with its seven fields having the values in the initializer; the reference to the object is returned and stored in the variable fib.
  • A reference to the array is passed as a parameter to the method reverse. The formal parameter a contains a reference to the same array pointeed to by the actual parameterfib.
  • A new array b of the same type and length as the parameter a is declared and allocated.
  • Each iteration of the for-loop moves one element from the first half of a to the second half of b and one element from the second half of a to the first half of b. Variables i and jcontain the indices of the two elements that are moved.
  • The reference to array b is returned. Although array referenced by b was allocated within the method call, it still exists after returning.
  • The reference that is returned is assigned to reversedFib.
Exercise The program has a bug. Fix it!

Array assignment can create garbage

Concept Since an array variable contains a reference to the array itself, if null or another value (another array of the same type) is assigned to the variable, the first array may no longer be accessible. Inaccessible memory is called garbage. The Java runtime system includes a garbage collector whose task is to return garbage to the pool of memory that can be allocated.
Program: Array05.java
// Learning Object Array05
//    array assignment can create garbage
public class Array05 {
    static int[] first(int[] a) {
        int[] b = new int[a.length/2];
        for (int i = 0; i < a.length / 2; i++)
            b[i] = a[i];
        return b;
    }
 
    public static void main(/*String[] args*/) {
        int[] fib = {0, 1, 1, 2, 3, 5, 8};
        fib = first(fib);
    }
}
An array referenced by the variable fib is passed as a parameter to a method that moves the values of the elements in the first half of the array fib into a new array b which is allocated in the method. The new array is returned to the main method and assigned to the variable fib, destroying the reference to the original array.
  • Initially, the variable fib of type integer array is allocated. As part of the same statement, the array object is created with its seven fields having the values in the initializer; the reference to the object is returned and stored in the variable fib.
  • A reference to the array is passed as a parameter to the method first. The formal parameter a contains a reference to the same array pointed to by the actual parameter fib.
  • A new array b of the same type as the parameter a but half the length is declared and allocated.
  • Each iteration of the for-loop moves one element from the first half of a to the corresponding element in the array b.
  • The reference to array b is returned. Although array referenced by b was allocated within the method call, it still exists after returning.
  • There are no references to the original array so it is inaccessible. Jeliot does not visualize garbage collection so the array remains visualized in the Instance and Array Area until the end of the program.
Exercise Modify the program so that the original array remains accessible in a different field.

Two-dimensional arrays

Concept A matrix can be stored in a two-dimensional array. The syntax is int[][] with two indices, the first for rows and the second for columns. To access an element of the array, expressions for the two indices must be givien.
Program: Array06.java
// Learning Object Array06
//     two-dimensional arrays
public class Array06 {
    static int addElements(int[][] a) {
        int sum = 0;
        for (int i = 0; i < a.length; i++)
            for (int j = 0; j < a[i].length; j++)
                sum = sum + a[i][j];
        return sum;
    }
 
    public static void main(/*String[] args*/) {
        int[][] matrix = new int[2][2];
        for (int i = 0; i < matrix.length; i++)
            for (int j = 0; j < matrix[i].length; j++)
                matrix[i][j] = i*matrix.length + j;
        int sum = addElements(matrix);
    }
}
This program creates a 2×2 matrix and computes the sum of its elements.
  • A two-dimensional array is allocated, the reference to it is assigned to the variable matrix. The variable matrix contains one reference for each row, and the rows are allocated as separate objects. Note that Jeliot displays each row from top to bottom as it does for all objects!
  • The elements of the array are initialized to (0,1,2,3) in a nested for-loop. The outside loop iterates over the rows and the inner loop iterates over the columns within an array.
  • matrix.length is used to get the number of rows and matrix[i].length to get the number of columns in row i, which is the same for all rows in this program.
  • The reference to the array is passed as a parameter to the method addElements, which adds the values of all the elements.
  • The sum is returned from the method and assigned to the variable sum.
Exercise Modify the program perform the same computation on a 2×3 matrix and on a 3×2 matrix.

Arrays of arrays

Concept A two-dimensional array is really an array of arrays; that is, each element of the array contains a reference to another array. Therefore, by using only one index a one-dimensional array is obtained.
Program: Array07.java
// Learning Object Array07
//    arrays of arrays
public class Array07 {
    public static void main(/*String[] args*/) {
        int[][] matrix = new int[2][2];
        for (int i = 0; i < matrix.length; i++)
            for (int j = 0; j < matrix[i].length; j++)
                matrix[i][j] = i*matrix.length + j;
        int[] vector = matrix[1];
    }
}
This program creates a 2×2 matrix and then assigns the second row to a variable of type one-dimensional array.
  • A two-dimensional array is allocated, the reference to it is assigned to the variable matrix. The variable matrix contains one reference for each row and the rows are allocated as separate objects. Note that Jeliot displays rows from top to bottom as it does for all objects!
  • The elements of the array are initialized to (0,1,2,3) in a nested for-loop. The outside loop iterates over the rows and the inner loop iterates over the columns within an array.
  • matrix.length is used to get the number of rows and matrix[i].length to get the number of columns in row i, which is the same for all rows in this program.
  • A variable vector of type one-dimensional array is declared and initialized with the second row of the matrix, matrix[1].
Exercise Write a program to rotate the rows of the array matrix. That is, row 0 becomes row 1 and row 1 becomes row 0. Now do this for an array of size 3×3: row 0 becomes row 1, row 1 becomes row 2 and row 2 becomes row 0.

Ragged Arrays

Concept A two-dimensional array is really an array of arrays; that is, each element of the array contains a reference to another array. However, the two-dimensional array need not be a square matrix, and each row can have a different number of elements. By using only one index a one-dimensional array is obtained and these arrays need not all be of the same size.
Program: Array08.java
// Learning Object Array08
//    ragged arrays
public class Array08 {
    static int addElements(int[][] a) {
        int sum = 0;
        for (int i = 0; i < a.length; i++)
            for (int j = 0; j < a[i].length; j++)
                sum = sum + a[i][j];
        return sum;
    }
 
    public static void main(/*String[] args*/) {
        int[][] matrix = new int[3][];
        int[] row0 = {0, 1, 2};
        int[] row1 = {3, 4};
        int[] row2 = {5};
        matrix[0] = row0;
        matrix[1] = row1;
        matrix[2] = row2;
        int sum = addElements(matrix);
    }
}
Here we create the upper-left triangle of a 3×3 matrix: row 0 of length 3, row 1 of length 2 and row 2 of length 1. Then we add the elements of the “ragged” array.
  • The variable matrix is allocated, but since the size of the rows is not given, it is allocated as a one-dimensional array whose elements are references to one-dimensional arrays of integers. The default value for the elements is null.
  • Three rows of different size are allocated with initializers and assigned to the elements of the array matrix.
  • A reference to matrix is passed to the method addElements which adds the elements of the array and returns the value.
  • matrix.length is used to get the number of rows and matrix[i].length to get the number of columns in row i; these are different for each row.
Exercise Simplify the allocation of the array matrix. First, show how the variables row can be eliminated. Then find out how to write an initializer for a two-dimensional array so that the array can be initialized in one declaration. (Note: initializers for two-dimensional arrays are not supported in Jeliot.)

Arrays of objects

Concept Arrays can contain references to arbitrary objects. There is no difference between these arrays and arrays whose values are of primitive type, except that an individual element can be of any type.
Program: Array09.java
// Learning Object Array09
//    arrays of objects
class Access {
    String name;
    int level;
    Access(String u, int l) {
        name = u; level = l;
    }
}
 
public class Array09 {
    static void swap(Access[] a, int i, int j) {
        Access temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
 
    public static void main(/*String[] args*/) {
        Access[] accesses = new Access[2];
        accesses[0] = new Access("Bob", 3);
        accesses[1] = new Access("Alice", 4);
        swap(accesses, 0, 1);
    }
}
Objects of class Access contain name of a bank customer and the access level permitted for that customer. This program creates two objects, assigns the their references to elements of the Access and then swaps the elements of the array.
  • The array accessess of type Access[] is allocated and contains null references.
  • An object of type Access are allocated and initialized by its constructor; a reference to the object is stored in the first element of the array accessess.
  • Similarly, another object is created and stored in the second element.
  • The array accessess is passed to the method swap along with the indices 0 and 1.
  • The two elements of the array are swapped. Note that after executing a[i] = a[j], both elements of the array point to the second object (Alice,4), while a reference to the first object (Bob,3) is saved in the variable temp.
Exercise Modify the program so that the initialization of the array accessess is done in one statement instead of three.
Exercise Explain what happens if the method swap is replaced by:
static void swap(Access a, Access b) {
  Access temp = a;
  a = b;
  b = temp;
}
and the call by swap(accesses[0], accesses[1]);

1 comment:

Related Posts Plugin for WordPress, Blogger...

java

Popular java Topics