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
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

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

  




 

 

Thinking in Java
Prev Contents / Index Next

A deep copy with ArrayList

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

//: appendixa:AddingClone.java
// 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();
    x2.increment();
    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(); )
      ((Int2)e.next()).increment();
    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