JMU
Arrays and References
An Introduction with Examples in Java


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Background
Review: An Array in Memory
images/array.gif
Review: Requirements
Arrays and References
An Example of Declaration and Instantiation

We can now look more closely at what happens when an array is declared and when it is instantiated.

    // Allocate four bytes to hold the address of the array
    // when it is created.  Add scores to the name table.
    //
    int[]     scores;


    // Allocate (from the heap) enough memory to hold
    // 5 int-values (20 bytes in total), initialize
    // each element to 0, and assign 5 to the 
    // final attribute named length (at that address).
    //
    // Then, store the address in the four bytes
    // named scores.
    //
    scores = new int[5];

    
An Example of Declaration and Instantiation (cont.)
images/JavaMemoryModel_IntArrayExample.png
The [ ] Operator
The Assignment Operator
An Example of Arrays of Objects

An array of objects is really an array of references.

    // Allocate four bytes to hold the address of the array
    // when it is created.  Add identity to the name table.
    //
    Color[]     identity;


    // Allocate enough memory to hold 2 addresses (8 bytes in total),
    // initialize each element to null, assign to to the (final) attribute
    // named length (at that address), and store the address of the
    // array in the four bytes named identity.
    //
    identity = new Color[2];


    // Allocate memory to hold each Color, initialize
    // the attributes of the objects, and put the address
    // in the appropriate element in the array.
    //
    identity[0] = new Color( 69,   0, 132);
    identity[1] = new Color(173, 156, 101);
    
An Example of Arrays of Objects (cont.)
images/JavaMemoryModel_ColorArrayExample.png
Arrays Declared to be final

The fact that arrays are reference types leads to some "surprises" about arrays that are declared to be final. Specifically, a reference can only be assigned to the array once, but values/references can be assigned to the elements of the array multiple times.

       final int[]  range;
       
       range    = new int[2];
       range[0] = 0;
       range[1] = 100;
       
       // These lines will compile
       range[0] = -1000;
       range[1] =  1000;       

       // This line will not compile
       range    = new int[2];
    
Comparing Arrays

The relational equals operator (i.e., ==) compares references. To compare elements, use the array's .equals() method or the Arrays.equals() method, but be careful since they rely on the elements .equals() method which may not do what you want.

javaexamples/basics/AkaArrays.java (Fragment: 0)
        int[]        a, b, c;

        a = new int[2];
        b = new int[2];
        
        a[0] = 10;
        a[1] = 100;
        
        b[0] = 10;
        b[1] = 100;
        
        c = a;

        if (a == b) System.out.println("a and b are aliases");
        if (a == c) System.out.println("a and c are aliases");
        if (b == c) System.out.println("b and c are aliases");
        
        if (a.equals(b)) System.out.println("a.equals(b) is true");
        if (a.equals(c)) System.out.println("a.equals(c) is true");
        if (b.equals(c)) System.out.println("b.equals(c) is true");

        if (Arrays.equals(a, b)) System.out.println("a and b have the same elements");
        if (Arrays.equals(a, c)) System.out.println("a and c have the same elements");
        if (Arrays.equals(b, c)) System.out.println("b and c have the same elements");
        
Arrays as Parameters

A copy of the reference is passed so the formal parameter is an alias for the actual parameter.

    // This function will swap the values of
    // elements 0 and 1 in the array duo
    //
    public static void swapElements(int[] duo)
    {
        int temp;


        temp   = duo[0];
        duo[0] = duo[1];
        duo[1] = temp;
    }
    
Arrays as Attributes
Arrays as Attributes (cont.)

Allocating Memory in the Constructor

public class GradeBook
{
    private double[] grades;
    private String   course;


    public GradeBook(String c, int n)
    {
        this.course = c;
        this.grades = new double[n];
    }

    // ...

    public double getGrade(int index)
    {
        if (index < this.grades.length) return this.grades[index];
        else                            return -1;
    }
}
    
    GradeBook   gb;

    gb = new GradeBook("CS100", 3);
    // ...
    System.out.printf("Grade %d: %f5.1\n", i, gb.getGrade(i));
    
Arrays as Attributes (cont.)

Passing the Array to the Constructor

public class GradeBook
{
    private double[] grades;
    private String   course;


    public GradeBook(String c, double[] g)
    {
        this.course = c;
        this.grades = g;
    }

    // ...

    public double getGrade(int index)
    {
        if (index < this.grades.length) return this.grades[index];
        else                            return -1;
    }
}
    
    double[]    exams = {100.0, 95.0, 100.0};
    GradeBook   gb;

    gb = new GradeBook("CS100", exams);
    // ...
    System.out.printf("Grade %d: %f5.1\n", 1, gb.getGrade(1));
    exams[1] = 10.0;
    System.out.printf("Grade %d: %f5.1\n", 1, gb.getGrade(1));
    
Arrays as Attributes (cont.)

Passing and Copying the Array

public class GradeBook
{
    private double[] grades;
    private String   course;


    public GradeBook(String c, double[] g)
    {
        int n;

        this.course = c;

        n = g.length;
        this.grades = new double[n];
        for (int i = 0; i < n; i++)
        {
            this.grades[i] = g[i];
        }
    }
}
    
    double[]    exams = {100.0, 95.0, 100.0};
    GradeBook   gb;

    gb = new GradeBook("CS100", exams);
    // ...
    System.out.printf("Grade %d: %f5.1\n", 1, gb.getGrade(1));
    exams[1] = 10.0;
    System.out.printf("Grade %d: %f5.1\n", 1, gb.getGrade(1));
    
Arrays as Attributes (cont.)
The clone() Method

clone() creates a shallow copy so each element in copy will contain the same reference as the corresponding element in original

    Movie[]     copy, original;

    original    = new Movie[4];
    original[0] = new Movie("Shrek", 2001);
    original[1] = new Movie("Toy Story", 1995);
    original[2] = new Movie("Monsters, Inc.", 2001);
    original[3] = new Movie("Who Framed Roger Rabbit", 1988) ;

    copy = original.clone();
    
java.util.Arrays Revisited

The methods in the java.util.Arrays utility class can change the elements in the arrays that they are passed because arrays are reference types.

    import java.util.Arrays;

    int     target;
    int[]   a;

    a = new int[100];

    Arrays.fill(a, 0);        // Fill a with zeroes
    Arrays.fill(a, 1, 10, 99) // Fill a[10] thru a[99] with ones

    ...

    Arrays.sort(a);           // Sort a in ascending order
    
An Aside: Variable-Length Parameter Lists
Variable-Length Parameter Lists (cont.)
Variable-Length Parameter Lists (cont.)
javaexamples/variadic/Numeric.java (Fragment: 0)
    /**
     * Calculate the maximum of a set of int values.
     *
     * @param  data   The int values of interest
     * @return        The maximum
     */
    public static int max(int... data)
    {
        int    result = data[0];

        for (int i=1; i<data.length; i++)
        {
            if (data[i] > result) result = data[i];
        }
        return result;
    }
        
javaexamples/variadic/Driver.java (Fragment: 0)
        int high = Numeric.max(90, 85, 50, 100, 20);