Complete the Enhanced for loop exercises before reviewing the solutions.

Review the exercise 3 solution with AP CS Tutor Brandon Horn.

Original code

Coordinate2D[] coors = new Coordinate2D[3];
coors[0] = new Coordinate2D(0, 0);
coors[1] = new Coordinate2D(1, 1);
coors[2] = new Coordinate2D(2, 2);

for(Coordinate2D d : coors)
{
    System.out.print(d + " ");
    d.setX(-1);
    System.out.println(d);
}

System.out.println(Arrays.toString(coors));

Output

(0, 0) (-1, 0)
(1, 1) (-1, 1)
(2, 2) (-1, 2)
[(-1, 0), (-1, 1), (-1, 2)]

Explanation

Each time an enhanced for loop runs, the loop variable is set to a copy of the value in the array. An array of objects is really an array of memory addresses (references). Each time the loop runs, both the loop variable (d in this code segment) and the array point to the same object.

Running a mutator method on the object to which the loop variable points changes the state of the object. The values inside the array coors are not changed. The state of the objects to which coors points are changed.

Step by step memory diagram

Step 1

Coordinate2D[] coors = new Coordinate2D[3];
coors[0] = new Coordinate2D(0, 0);
coors[1] = new Coordinate2D(1, 1);
coors[2] = new Coordinate2D(2, 2);

// more code not yet run

Memory diagram after Step 1

The diagram shows coors pointing to a box representing the array. Each spot in the array points to a box representing a Coordinate2D object. The first object contains x: 0, y: 0. The second object contains x: 1, y: 1. The third object contains x: 2, y: 2.

So far, this is the same code as in Exercise 2, so the memory diagram is the same.

An array of objects is really an array of references. Each position in coors stores the memory address of a Coordinate2D object (the arrow pointing to the object). The array itself is also an object so coors stores the memory address of the array.

Step 2

Coordinate2D[] coors = new Coordinate2D[3];
coors[0] = new Coordinate2D(0, 0);
coors[1] = new Coordinate2D(1, 1);
coors[2] = new Coordinate2D(2, 2);

for(Coordinate2D d : coors)
{
    System.out.print(d + " ");
    // more code not yet run
}

// more code not yet run

Step 2 is inside the first iteration of the enhanced for loop, immediately after the print statement has been run.

Memory diagram after Step 2

The diagram shows coors pointing to a box representing the array. Each spot in the array points to a box representing a Coordinate2D object. The first object contains x: 0, y: 0. The second object contains x: 1, y: 1. The third object contains x: 2, y: 2. The diagram shows the variable d pointing to the box representing the Coordinate2D object that contains x: 0, y: 0.

This is also the same code as in Exercise 2, except for the loop variable name.

The first time the enhanced for loop runs, d is set to a copy of the value at coors[0]. The value at coors[0] is the memory address of the object containing x: 0, y: 0 (the arrow). In other words, d and coors[0] point to the same object.

Output after Step 2

(0, 0) 

The print statement prints the object to which d points, which is the same object to which coors[0] points. The object contains x: 0, y: 0.

Step 3

Coordinate2D[] coors = new Coordinate2D[3];
coors[0] = new Coordinate2D(0, 0);
coors[1] = new Coordinate2D(1, 1);
coors[2] = new Coordinate2D(2, 2);

for(Coordinate2D d : coors)
{
    System.out.print(d + " ");
    d.setX(-1);
    System.out.println(d);
}

// more code not yet run

Step 3 is inside the first iteration of the enhanced for loop, immediately after the println statement has been run.

Memory diagram after Step 3

The diagram shows coors pointing to a box representing the array. Each spot in the array points to a box representing a Coordinate2D object. The first object contains x: -1, y: 0. The second object contains x: 1, y: 1. The third object contains x: 2, y: 2. The diagram shows the variable d pointing to the same box as the first spot in the array, the box containing x: -1, y: 0.

This step diverges from Exercise 2. d.setX(-1); runs the setX method on the object to which d points. This is the same object to which coors[0] points. The value of coors[0] is not changed. The state of the object to which both d and coors[0] point is changed.

Output after Step 3

(0, 0) (-1, 0)

The println statement prints the object to which d points. The object contains x: -1, y: 0.

Step 4

Coordinate2D[] coors = new Coordinate2D[3];
coors[0] = new Coordinate2D(0, 0);
coors[1] = new Coordinate2D(1, 1);
coors[2] = new Coordinate2D(2, 2);

for(Coordinate2D d : coors)
{
    System.out.print(d + " ");
    d.setX(-1);
    System.out.println(d);
}

System.out.println(Arrays.toString(coors));

Step 4 is after the entire code segment has executed.

Memory diagram after Step 4

The diagram shows coors pointing to a box representing the array. Each spot in the array points to a box representing a Coordinate2D object. The first object contains x: -1, y: 0. The second object contains x: -1, y: 1. The third object contains x: -1, y: 2.

As in Exercise 2, the values in the array to which coors points remain unchanged. Unlike in Exercise 2, the values of x inside the objects to which the array points have all been changed to -1.

The scope of d is the loop. d does not exist after the loop finishes.

Output after Step 4

(0, 0) (-1, 0)
(1, 1) (-1, 1)
(2, 2) (-1, 2)
[(-1, 0), (-1, 1), (-1, 2)]

Each time the loop runs, the code segment prints the object to which d refers before and after the mutator method setX is run.

The println statement outside the loop prints the entire array. Although the array itself contains its original values (the memory addresses), each object to which the array points now contains -1 as its x value.

Note: Arrays.toString returns a formatted String containing the values in its array parameter. Arrays.toString is not part of the AP CS A Java Subset.

Comments

Comment on Enhanced for loop exercises