Tuesday, 22 July 2014

Shallow copy and Deep Copy

clone method performs shallow copying. A shallow copy just copies the values of the references in the class. Lets see it by an example.

Lets take a Student class, which contains 'marks' object and two fields(name, id).



If we clone Student s1 as Student s2. Then fields other than reference variables are copied as separate variables, but the reference variable 'marks' is same for both student s1 and s2. I.e, a shallow copy just copies the values of the references in the class. So changes to the marks object by student s1 is reflected to s2 and vice versa.

public class Marks {
    int maths, physics, chemistry;
    
    Marks(int m, int p, int c){
        maths = m;
        physics = p;
        chemistry = c;
    }
}

class Student implements Cloneable{
    int id;
    String name;
    Marks marks;
    
    Student(int id, String name, Marks marks){
        this.id = id;
        this.name = name;
        this.marks = marks;
    }
    
    void printMarks(){
        System.out.println("Maths: " + marks.maths);
        System.out.println("Physics: " + marks.physics);
        System.out.println("Chemistry: " + marks.chemistry);
    }
    
    @Override
    public String toString(){
        return id + "." + name;
    }
    
    @Override
    public Object clone() throws CloneNotSupportedException{
        return super.clone();
    }
}

public class ShallowCopy {
    public static void main(String args[]) throws CloneNotSupportedException{
        Marks m1 = new Marks(95, 96, 75);
        
        Student s1 = new Student(1, "Krishna", m1);
        Student s2 = (Student) s1.clone();
        
        System.out.println("For student s1");
        System.out.println(s1);
        s1.printMarks();
        
        System.out.println("For student s2");
        System.out.println(s2);
        s2.printMarks();
        
        System.out.println("change marks of student s2");
        s2.marks.maths = 35;
        s2.marks.physics = 45;
        s2.marks.chemistry = 55;
        
        System.out.println("Change the name and id of student s2");
        s2.name = "Hari";
        s2.id = 2;
        
        System.out.println("For student s1");
        System.out.println(s1);
        s1.printMarks();
        
        System.out.println("For student s2");
        System.out.println(s2);
        s2.printMarks();
    }
}

Output
For student s1
1.Krishna
Maths: 95
Physics: 96
Chemistry: 75
For student s2
1.Krishna
Maths: 95
Physics: 96
Chemistry: 75
change marks of student s2
Change the name and id of student s2
For student s1
1.Krishna
Maths: 35
Physics: 45
Chemistry: 55
For student s2
2.Hari
Maths: 35
Physics: 45
Chemistry: 55

Observe the output, the marks changed by Student s2 are reflected to s1, but not the name and id(Since these are not references).

Deep Copy
A shallow copy is a copy of the reference pointer to the object, whereas a deep copy is a copy of the object itself. We can achieve deep copy using Serialization.

import java.io.Serializable;
public class Marks implements Serializable{
    int maths, physics, chemistry;
    
    Marks(int m, int p, int c){
        maths = m;
        physics = p;
        chemistry = c;
    }
}

import java.io.Serializable;

class Student implements Serializable{
    int id;
    String name;
    Marks marks;
    
    Student(int id, String name, Marks marks){
        this.id = id;
        this.name = name;
        this.marks = marks;
    }
    
    void printMarks(){
        System.out.println("Maths: " + marks.maths);
        System.out.println("Physics: " + marks.physics);
        System.out.println("Chemistry: " + marks.chemistry);
    }
    
    @Override
    public String toString(){
        return id + "." + name;
    }
}

import java.io.*;
public class DeepCopy {
    public static void main(String args[]) throws FileNotFoundException, IOException, ClassNotFoundException{
        Marks m1 = new Marks(95, 96, 75);
        
        Student s1 = new Student(1, "Krishna", m1);
        
        try (FileOutputStream fileOut = new FileOutputStream("student.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut);) {
            out.writeObject(s1);
            out.close();
        }
        
        Student s2;
        try (FileInputStream fileIn = new FileInputStream("student.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn);) {
            s2 = (Student) in.readObject();
            in.close();
        }
         
        System.out.println("For student s1");
        System.out.println(s1);
        s1.printMarks();
        
        System.out.println("For student s2");
        System.out.println(s2);
        s2.printMarks();
        
        System.out.println("change marks of student s2");
        s2.marks.maths = 35;
        s2.marks.physics = 45;
        s2.marks.chemistry = 55;
        
        System.out.println("Change the name and id of student s2");
        s2.name = "Hari";
        s2.id = 2;
        
        System.out.println("For student s1");
        System.out.println(s1);
        s1.printMarks();
        
        System.out.println("For student s2");
        System.out.println(s2);
        s2.printMarks();
    }
}

Output
For student s1
1.Krishna
Maths: 95
Physics: 96
Chemistry: 75
For student s2
1.Krishna
Maths: 95
Physics: 96
Chemistry: 75
change marks of student s2
Change the name and id of student s2
For student s1
1.Krishna
Maths: 95
Physics: 96
Chemistry: 75
For student s2
2.Hari
Maths: 35
Physics: 45
Chemistry: 55



                                                 Home

No comments:

Post a Comment