250 likes | 413 Views
public String s1,s2; s1 = "This is a String!!"; s2 = s1;. String. String class objects are immutable. public String s; s = "This is a String!!"; s = s.toUpperCase();. public String s; s = "This is a String!!"; ChangeToUpper(s);. public void ChangeToUpper (String s) {
E N D
public String s1,s2; s1 = "This is a String!!"; s2 = s1; String String class objects are immutable public String s; s = "This is a String!!"; s = s.toUpperCase(); ITK 275
public String s; s = "This is a String!!"; ChangeToUpper(s); public void ChangeToUpper (String s) { s = s.toUpperCase(); } String This function does not have any side effect String class objects are immutable ITK 275
int[] a; a = new int[4]; for (int i=0;i<a.length;i++) a[i] = i*i; } swap(a,1,2); public void swap(int[] a, int i, int j){ int temp; temp = a[i]; a[i]=a[j]; a[j]=temp; } Array is mutable ITK 275
... int a = new int[6]; ... ... RenewArray(a,4); // renew array a to size 4 ... ... Any Problem? Renew an Array public staticvoid RenewArray(int[] a, int size) { ... a = newint[size]; ... ... } size 4 a a How to fix? ITK 275
... int a = new int[6]; ... ... a = RenewArray(a,4); // renew array a to size 4 ... ... public staticint[] RenewArray(int[] a, int size) { ... a = newint[size]; ... ... return a; } Renew an Array size 4 a a ITK 275
class Stack { private int size,top=-1; private int[] stk; ..... } Copy the reference public static void main(...) { Stack a,b; a = new Stack(4); .... b = a; .... } ...... ITK 275
class Stack { private int size,top=-1; private int[] stk; ..... } Shallow Copy Shall copy can be done by the default clone public static void main(...) { Stack a,b; a = new Stack(4); .... b = (Stack) a.clone(); .... } ...... ...... Shallow Copy ITK 275
Shall copy can be done by the default clone publicclass SillyStack implements Cloneable { publicintsize,top=-1; publicint[] stk; .... .... public Object clone() { try { return (Object) super.clone(); } catch(CloneNotSupportedException e) { returnnull; } } .... } marker interface Cloneable ITK 275
class Stack { private int size,top=-1; private int[] stk; ..... } Deep Copy Deep copy needs to be programed by the programmer public static void main(...) { Stack a,b; a = new Stack(4); .... b = (Stack) a.clone(); .... } ...... ...... Shallow Copy Deep Copy ITK 275
Using the copy constructor public static void main(...) { Stack a,b; a = new Stack(4); .... b = Stack(a); .... } publicclass Stack implements Cloneable { publicintsize, top=-1; publicint[] stk; .... .... // This is the copy constructor public Stack(Stack s) { this.top = s.top; this.size = s.size; this.stk = newint[this.size]; for (int i=0;i<this.size;i++) { this.stk[i] = s.stk[i]; } } .... } Copy constructor for deep copy ITK 275
Using the clone method Clone method for deep copy public static void main(...) { Stack a,b; a = new Stack(4); .... b = (Stack) a.clone(); .... } publicclass Stack implements Cloneable { publicintsize, top=-1; publicint[] stk; .... .... public Object clone() { Stack newStack; newStack = new Stack(this.size); newStack.top = this.top; for (int i=0;i<this.size;i++){ newStack.stk[i] = stk[i]; } return (Object) newStack; } .... } Why bother? Why can we just use copy constructor? ITK 275
public class A { public int a; public A(int a) {// This is the constructor this.a = a; } public A(A obj) { // This is the copy constructor this.a = obj.a; } public String print() { return "- : "+this.a; } } Copy constructor vs. clone ITK 275
public class B extends A { public int b; public B(int b) { // constructor super(b+1); this.b = b; } public B(B obj) { // copy constructor super(obj);// call the copy constructor // of the super class this.b=obj.b; } public String print() { return super.print()+" : "+this.b; } } Subclass B ITK 275
public class C extends B { public int c; public C(int c) { // constructor super(c+1); this.c = c; } public C(C obj) { // copy constructor super(obj); // call the copy constructor// of the super class this.c = obj.c; } public String print() { return super.print()+" : "+this.c; } } Subclass C ITK 275
A[] a = new A[2]; B[] b = new B[2]; C[] c = new C[2]; for (int i=0; i<2; i++) { a[i] = new A(i); b[i] = new B(i); c[i] = new C(i); } printArray(a,b,c); System.out.println("**"); for (int i=0; i<2; i++) { a[i] = b[i]; b[i] = c[i]; c[i].a = 100; } printArray(a,b,c); Arrays of A, B, C [0] - : 0 - : 1 : 0 - : 2 : 1 : 0 [1] - : 1 - : 2 : 1 - : 3 : 2 : 1 ** ITK 275
A[] a = new A[2]; B[] b = new B[2]; C[] c = new C[2]; for (int i=0; i<2; i++) { a[i] = new A(i); b[i] = new B(i); c[i] = new C(i); } printArray(a,b,c); System.out.println("**"); for (int i=0; i<2; i++) { a[i] = b[i]; b[i] = c[i]; c[i].a = 100; } printArray(a,b,c); Simple Assignment 100 . . . . . . . ** [0] - : 1 : 0 - : 100 : 1 : 0 - : 100 : 1 : 0 [1] - : 2 : 1 - : 100 : 2 : 1 - : 100 : 2 : 1 100 ITK 275
A[] a = new A[2]; B[] b = new B[2]; C[] c = new C[2]; for (int i=0; i<2; i++) { a[i] = new a(i); b[i] = new b(i); c[i] = new c(i); } printArray(a,b,c); System.out.println("**"); for (int i=0; i<2; i++) { a[i] = new B(b[i]); b[i] = new C(c[i]); c[i].a = 100; } printArray(a,b,c); Using copy constructor 100 . . . . . . . ** [0] - : 1 : 0 - : 2 : 1 : 0 - : 100 : 1 : 0 [1] - : 2 : 1 - : 3 : 2 : 1 - : 100 : 2 : 1 100 ITK 275
A[] a = new A[2]; B[] b = new B[2]; C[] c = new B[2]; for (int i=0; i<2; i++) { a[i] = new A(i); b[i] = new B(i); c[i] = new C(i); } printArray(a,b,c); System.out.println("**"); ACopy(c,a); // copy c to a printArray(a,b,c); Problem of using copy constructor ……………………………………… ** [0] - : 2 - : 1 : 0 - : 2 : 1 : 0 [1] - : 3 - : 2 : 1 - : 3 : 2 : 1 // copy x to y public static void ACopy(A[] x, A[] y) { for (int i=0; i<x.length; i++) y[i] = new A(x[i]); } ITK 275
Marker interface public class X implements Cloneable { public int x; public X(int x) { this.x = x; } public X(X obj) { // This is the copy constructor this.x = obj.x; } public String print() { return ": "+x; } public Object clone() { X n; try { n = (X) super.clone(); } catch (CloneNotSupportedException e) { return null; } n.x = this.x; return (Object) n; } } Superclass X implements Cloneable To handle exception when super is not cloneable ITK 275
public class Y extends X implements Cloneable{ public int y; public Y(int y) { // constructor super(y+1); this.y = y; } public Y(Y obj) { // copy constructor super(obj); // call the super’s constructor this.y = obj.y; } public Object clone() { Y n; n = (Y) super.clone(); // super is cloneable n.y = this.y; return (Object) n; } public String print() { return super.print()+" : "+y; } } Subclass Y ITK 275
public class Z extends Y implements Cloneable{ public int z; public Z(int z) { // constructor super(z+1); this.z = z; } public Z(Z obj) { // copy constructor super(obj); // call the super’s constructor this.z = obj.z; } public Object clone() { Z n; n = (Z) super.clone(); // super is cloneable n.z = this.z; return (Object) n; } public String print() { return super.print()+" : "+z; } } Subclass Z ITK 275
...... for (int i=0; i<2; i++) { x[i] = new X(i); y[i] = new Y(i); z[i] = new Z(i); } AClone(y,x); AClone(z,y); printArray(x,y,z); Using clone method // clone a to b public static void AClone(X[] a, X[] b) { for (int i=0; i<a.length; i++) b[i] = (X) (a[i].clone()); } [0] - : 1 : 0 - : 2 : 1 : 0 - : 2 : 1 : 0 [1] - : 2 : 1 - : 3 : 2 : 1 - : 3 : 2 : 1 ITK 275
clone method dynamic determined during the running time copy-constructor statics determined during the compiling time The difference between copy-constructor and clone method // copy x to y public static void ACopy(A[] x, A[] y) { for (int i=0; i<x.length; i++) y[i] = new A(x[i]); } // clone a to b public static void AClone(X[] a, X[] b) { for (int i=0; i<a.length; i++) b[i] = (X) (a[i].clone()); } ITK 275