Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Mail Systems
Eclipse Documentation

How To Guides
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Problem Solutions
Privacy Policy




Thinking in Java
Prev Contents / Index Next

A deep copy with ArrayList

Let’s revisit from earlier in this appendix. This time the Int2 class is cloneable, so the ArrayList can be deep copied:

// You must go through a few gyrations
// to add cloning to your own class.
import com.bruceeckel.simpletest.*;
import java.util.*;

class Int2 implements Cloneable {
  private int i;
  public Int2(int ii) { i = ii; }
  public void increment() { i++; }
  public String toString() { return Integer.toString(i); }
  public Object clone() {
    Object o = null;
    try {
      o = super.clone();
    } catch(CloneNotSupportedException e) {
      System.err.println("Int2 can't clone");
    return o;

// Inheritance doesn't remove cloneability:
class Int3 extends Int2 {
  private int j; // Automatically duplicated
  public Int3(int i) { super(i); }

public class AddingClone {
  private static Test monitor = new Test();
  public static void main(String[] args) {
    Int2 x = new Int2(10);
    Int2 x2 = (Int2)x.clone();
    System.out.println("x = " + x + ", x2 = " + x2);
    // Anything inherited is also cloneable:
    Int3 x3 = new Int3(7);
    x3 = (Int3)x3.clone();
    ArrayList v = new ArrayList();
    for(int i = 0; i < 10; i++ )
      v.add(new Int2(i));
    System.out.println("v: " + v);
    ArrayList v2 = (ArrayList)v.clone();
    // Now clone each element:
    for(int i = 0; i < v.size(); i++)
      v2.set(i, ((Int2)v2.get(i)).clone());
    // Increment all v2's elements:
    for(Iterator e = v2.iterator(); e.hasNext(); )
    System.out.println("v2: " + v2);
    // See if it changed v's elements:
    System.out.println("v: " + v);
    monitor.expect(new String[] {
      "x = 10, x2 = 11",
      "v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]",
      "v2: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]",
      "v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"
} ///:~

Int3 is inherited from Int2, and a new primitive member, int j, is added. You might think that you’d need to override clone( ) again to make sure j is copied, but that’s not the case. When Int2’s clone( ) is called as Int3’s clone( ), it calls Object.clone( ), which determines that it’s working with an Int3 and duplicates all the bits in the Int3. As long as you don’t add references that need to be cloned, the one call to Object.clone( ) performs all of the necessary duplication regardless of how far down in the hierarchy clone( ) is defined.

You can see what’s necessary in order to do a deep copy of an ArrayList: After the ArrayList is cloned, you have to step through and clone each one of the objects pointed to by the ArrayList. You’d have to do something similar to this to do a deep copy of a HashMap.

The remainder of the example shows that the cloning did happen by showing that, once an object is cloned, you can change it, and the original object is left untouched.
Thinking in Java
Prev Contents / Index Next

   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire