Section 11.21 Worked Example: Shallow and Deep Copies
Subgoals for Evaluating Arrays.
-
Declaring and initialization of array
-
Set up a one dimensional table (i.e., one row) with 0 to (size - 1) elements
-
Upon instantiation of an array object, all elements contain default value for datatype stored in array OR values from the initializer list
-
-
Determine access or change of element, or action on entire array object, and update slots as needed (remembering assignment subgoals)
-
Accessing array element
-
Evaluate expression within [ ] which will be the index for element to be accessed
-
arrayName[index]
returns value stored at that index -
index must be between 0 and
arrayName.length
- 1, inclusive otherwiseIndexOutOfBounds
exception occurs
-
-
Changing value of an array element
-
Evaluate expression within [ ] which will be the index for element to be accessed
-
arrayName[index]
will now contain the value on the RHS of assignment statement -
(remember the assignment subgoals for verifying data types and evaluating expressions)
-
(remember rules for index values)
-
-
Whole array actions
-
Pass as argument - a copy of the reference to the instantiated array is passed to the method. This means that any changes made to the array elements inside the method are persistent. The one exception to this is if you assign the argument to reference a different array in memory.
-
Assignment - changes the reference to point to the array on the RHS of the assignment operator.
-
Subsection 11.21.1
Problem: Evaluate the following code - what is the output?
public static void main(String[] args) {
Person [] people = new Person[3];
Person maria = new Person("Maria Santos", 156);
people[0] = maria;
people[1] = new Person("Caiji Zheng", 742);
people[2] = new Person("Mary Smith", 548);
Person[] morePeople = new Person[people.length];
morePeople = people;
morePeople[1].setName("Mickey Mouse");
System.out.println("people contains " + printObjArr(people));
System.out.println("morePeople contains " + printObjArr(morePeople));
/**********************************************************************/
morePeople = new Person[people.length];
for (int x = 0; x < people.length; x++)
morePeople[x] = people[x];
morePeople[1].setName("Donald Duck");
System.out.println("people contains " + printObjArr(people));
System.out.println("morePeople contains " + printObjArr(morePeople));
/**********************************************************************/
morePeople = new Person[people.length];
for (int x = 0; x < people.length; x++)
morePeople[x] = new Person(people[x].getName(), people[x].getId());
morePeople[1].setName("Goofy");
System.out.println("people contains " + printObjArr(people));
System.out.println("morePeople contains " + printObjArr(morePeople));
}
public static String printObjArr(Object[] arr) {
String result = "";
for (Object o : arr) {
result += o;
result += " ";
}
return result;
}
This code also makes use of a
Person
class, which is defined here:
public class Person {
private String name; // name of person
private int id; // person's id
// overloaded constructor
public Person(String name, int id) {
setName(name);
setId(id);
}
// default constructor
public Person() {
}
// Accessors and Mutators
public String getName() {
return name;
}
public void setName(String name) {
if (name.length() != 0) // name must not be null
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// toString to allow conversion to String
public String toString() {
return "Person{" + "name='" + name + '\'' + ", id=" + id + '}';
}
}
Subsection 11.21.2 SG1: Declaring and initialization of array
The first 6 lines of the
main()
method are declaring and initializing an array of Person object references:
Person [] people = new Person[3];
Person maria = new Person("Maria Santos", 156);
people[0] = maria;
people[1] = new Person("Caiji Zheng", 742);
people[2] = new Person("Mary Smith", 548);
Person[] morePeople = new Person[people.length];
Here is a memory representation:

Notice that at this point the array
morePeople
just contains values of null, but has the same number of elements as the array people
. Also notice that you can access the Person object representing Miara Santos through the variable maria
or people[0]
. When you have two variables that access the same object, we say the variables alias one another.
Subsection 11.21.3 SG2: Determine access or action, SG5: Whole array actions, array assignment
The next line of code assigns the variable people to the variable morePeople:
morePeople = people;
They are now aliases of each other - the variables
people
and morePeople
point to the same array! Here is the memory representation:

So these next statements:
morePeople[1].setName("Mickey Mouse");
System.out.println("people contains " + printObjArr(people));
System.out.println("morePeople contains " + printObjArr(morePeople));

Will generate this output:
people contains Person{name=’Maria Santos’, id=156} Person{name=’Mickey Mouse’, id=742} Person{name=’Mary Smith’, id=548}
morePeople contains Person{name=’Maria Santos’, id=156} Person{name=’Mickey Mouse’, id=742} Person{name=’Mary Smith’, id=548}
Subsection 11.21.4 SG2: Determine access or action
Let’s look at the next section of code:
morePeople = new Person[people.length];
for (int x = 0; x < people.length; x++)
morePeople[x] = people[x];
Here we have allocated new memory for the
morePeople
array (so memory looks like figure 11.22.1 except that the name for the instance in element index 1 is still "Mickey Mouse").
The for loop assigns the reference in each element of
people
to the corresponding element in morePeople
. So now memory looks like:

This is known as a shallow copy - copying only the references. This makes each element of the
people
array an alias to the corresponding element in the morePeople
array.
The next lines of code:
morePeople[1].setName("Donald Duck");
System.out.println("people contains " + printObjArr(people));
System.out.println("morePeople contains " + printObjArr(morePeople));
will result in the name value in the
morePeople[1]
reference changing:

Thus the output generated is:
people contains Person{name=’Maria Santos’, id=156} Person{name=’Donald Duck’, id=742} Person{name=’Mary Smith’, id=548}
morePeople contains Person{name=’Maria Santos’, id=156} Person{name=’Donald Duck’, id=742} Person{name=’Mary Smith’, id=548}
Subsection 11.21.5 SG2: Determine access or action
Let’s look at the last section of code:
morePeople = new Person[people.length];
for (int x = 0; x < people.length; x++)
morePeople[x] = new Person(people[x].getName(), people[x].getId());
Here we have allocated new memory for the
morePeople
array (so memory looks like figure 11.22.1 except that the name for the instance in element index 1 is still "Donald Duck" ).
The for loop assigns the reference in each element of
people
to a new Person instance with the values from the corresponding element in morePeople
. So now memory looks like:

This is known as a deep copy - making new instances with identical values. Now there are no aliases and the objects are independent.
The next lines of code:
morePeople[1].setName("Goofy");
System.out.println("people contains " + printObjArr(people));
System.out.println("morePeople contains " + printObjArr(morePeople));
Will only change the morePeople[1] name value. Memory looks like:

And the output generated is:
people contains Person{name=’Maria Santos’, id=156} Person{name=’Donald Duck’, id=742} Person{name=’Mary Smith’, id=548}
morePeople contains Person{name=’Maria Santos’, id=156} Person{name=’Goofy’, id=742} Person{name=’Mary Smith’, id=548}
Subsection 11.21.6
What is the output produced by the code?
Answer.
people contains Person{name=’Maria Santos’, id=156} Person{name=’Mickey Mouse’, id=742} Person{name=’Mary Smith’, id=548}
morePeople contains Person{name=’Maria Santos’, id=156} Person{name=’Mickey Mouse’, id=742} Person{name=’Mary Smith’, id=548}
people contains Person{name=’Maria Santos’, id=156} Person{name=’Donald Duck’, id=742} Person{name=’Mary Smith’, id=548}
morePeople contains Person{name=’Maria Santos’, id=156} Person{name=’Donald Duck’, id=742} Person{name=’Mary Smith’, id=548}
people contains Person{name=’Maria Santos’, id=156} Person{name=’Donald Duck’, id=742} Person{name=’Mary Smith’, id=548}
morePeople contains Person{name=’Maria Santos’, id=156} Person{name=’Goofy’, id=742} Person{name=’Mary Smith’, id=548}
You have attempted of activities on this page.