Complete the Arrays of objects exercises before reviewing the solutions.
Review the Arrays of objects exercise 1 solution with AP CS Tutor Brandon Horn.
Original code
Coordinate2D[] coors = new Coordinate2D[3];
coors[0] = new Coordinate2D(1, 1);
coors[1] = new Coordinate2D(2, 2);
coors[2] = new Coordinate2D(3, 3);
System.out.println(Arrays.toString(coors));
// prints: [(1, 1), (2, 2), (3, 3)]
Coordinate2D[] coors2 = new Coordinate2D[3];
for(int i = 0; i < coors2.length; i++)
coors2[i] = coors[i];
coors2[0] = new Coordinate2D(4, 4);
coors2[1].setX(5);
coors2[1].setY(5);
System.out.println(Arrays.toString(coors));
System.out.println(Arrays.toString(coors2));
Output
[(1, 1), (2, 2), (3, 3)]
[(1, 1), (5, 5), (3, 3)]
[(4, 4), (5, 5), (3, 3)]
Explanation
An array of objects is really an array of references (memory addresses). (More generally, an array is a bunch of values of the same type stored in sequential memory locations.)
The statement coors2[i] = coors[i];
copies the memory address stored at coors[i]
into coors2[i]
. It does not copy the object to which coors[i]
refers.
At the end of the for
loop, both coors
and coors2
refer to the same 3 objects. The Coordinate2D
objects themselves are neither copied nor changed. This is known as creating a shallow copy of the array.
The statement coors2[0] = new Coordinate2D(4, 4);
creates a new Coordinate2D
object representing (4, 4)
and stores its memory address in coors2[0]
. This has no effect on coors
, coors[0]
, or the object to which coors[0]
refers.
The statements coors2[1].setX(5);
and coors2[1].setY(5);
run the mutator methods setX
and setY
on the object to which coors2[1]
refers. coors[i]
refers to the same object. The values being changed are those of the instance variables x
and y
inside the object. The values of coors2[1]
and coors[1]
(the memory address of the object) remain unchanged.
Step by step memory diagram
Step 1
Coordinate2D[] coors = new Coordinate2D[3];
coors[0] = new Coordinate2D(1, 1);
coors[1] = new Coordinate2D(2, 2);
coors[2] = new Coordinate2D(3, 3);
System.out.println(Arrays.toString(coors));
// prints: [(1, 1), (2, 2), (3, 3)]
Coordinate2D[] coors2 = new Coordinate2D[3];
// additional code not yet run
Memory diagram after Step 1
The default value for elements of an array of objects (really an array of memory addresses) is null
.
Output after Step 1
[(1, 1), (2, 2), (3, 3)]
Step 2
Coordinate2D[] coors = new Coordinate2D[3];
coors[0] = new Coordinate2D(1, 1);
coors[1] = new Coordinate2D(2, 2);
coors[2] = new Coordinate2D(3, 3);
System.out.println(Arrays.toString(coors));
// prints: [(1, 1), (2, 2), (3, 3)]
Coordinate2D[] coors2 = new Coordinate2D[3];
for(int i = 0; i < coors2.length; i++)
coors2[i] = coors[i];
// additional code not yet run
Memory diagram after Step 2
The statement coors2[i] = coors[i];
copies the memory address stored at coors[i]
into coors2[i]
. It does not copy the object to which coors[i]
refers.
At the end of the for
loop, both coors
and coors2
refer to the same 3 objects. The Coordinate2D
objects themselves are neither copied nor changed. This is known as creating a shallow copy of the array.
Step 3
Coordinate2D[] coors = new Coordinate2D[3];
coors[0] = new Coordinate2D(1, 1);
coors[1] = new Coordinate2D(2, 2);
coors[2] = new Coordinate2D(3, 3);
System.out.println(Arrays.toString(coors));
// prints: [(1, 1), (2, 2), (3, 3)]
Coordinate2D[] coors2 = new Coordinate2D[3];
for(int i = 0; i < coors2.length; i++)
coors2[i] = coors[i];
coors2[0] = new Coordinate2D(4, 4);
// additional code not yet run
Memory diagram after Step 3
The statement coors2[0] = new Coordinate2D(4, 4);
creates a new Coordinate2D
object representing (4, 4)
and stores its memory address in coors2[0]
. This has no effect on coors
, coors[0]
, or the object to which coors[0]
refers.
Step 4
Coordinate2D[] coors = new Coordinate2D[3];
coors[0] = new Coordinate2D(1, 1);
coors[1] = new Coordinate2D(2, 2);
coors[2] = new Coordinate2D(3, 3);
System.out.println(Arrays.toString(coors));
// prints: [(1, 1), (2, 2), (3, 3)]
Coordinate2D[] coors2 = new Coordinate2D[3];
for(int i = 0; i < coors2.length; i++)
coors2[i] = coors[i];
coors2[0] = new Coordinate2D(4, 4);
coors2[1].setX(5);
coors2[1].setY(5);
System.out.println(Arrays.toString(coors));
System.out.println(Arrays.toString(coors2));
Memory diagram after Step 4
The statements coors2[1].setX(5);
and coors2[1].setY(5);
run the mutator methods setX
and setY
on the object to which coors2[1]
refers. coors[i]
refers to the same object. The values being changed are those of the instance variables x
and y
inside the object. The values of coors2[1]
and coors[1]
(the memory address of the object) remain unchanged.
Output after Step 4
[(1, 1), (2, 2), (3, 3)]
[(1, 1), (5, 5), (3, 3)]
[(4, 4), (5, 5), (3, 3)]