<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    gembin

    OSGi, Eclipse Equinox, ECF, Virgo, Gemini, Apache Felix, Karaf, Aires, Camel, Eclipse RCP

    HBase, Hadoop, ZooKeeper, Cassandra

    Flex4, AS3, Swiz framework, GraniteDS, BlazeDS etc.

    There is nothing that software can't fix. Unfortunately, there is also nothing that software can't completely fuck up. That gap is called talent.

    About Me

     

    Deep Copy And Shallow Copy

    Lets first separate it out and see what each one means.

    What is Shallow Copy?

    Shallow copy is a bit-wise copy of an object. A new object is created that has an exact copy of the values in the original object. If any of the fields of the object are references to other objects, just the reference addresses are copied i.e., only the memory address is copied.

    Shallow Copy

    In this figure, the MainObject1 have fields "field1" of int type, and "ContainObject1" of ContainObject type. When you do a shallow copy of MainObject1, MainObject2 is created with "field3" containing the copied value of "field1" and still pointing to ContainObject1 itself. Observe here and you will find that since field1 is of primitive type, the values of it are copied to field3 but ContainedObject1 is an object, so MainObject2 is still pointing to ContainObject1. So any changes made to ContainObject1 in MainObject1 will reflect in MainObject2.

    Now if this is shallow copy, lets see what's deep copy?

    What is Deep Copy?

    A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. A deep copy occurs when an object is copied along with the objects to which it refers.

    Deep Copy

    In this figure, the MainObject1 have fields "field1" of int type, and "ContainObject1" of ContainObject type. When you do a deep copy of MainObject1, MainObject2 is created with "field3" containing the copied value of "field1" and "ContainObject2" containing the copied value of ContainObject1.So any changes made to ContainObject1 in MainObject1 will not reflect in MainObject2.

    Well, here we are with what shallow copy and deep copy are and obviously the difference between them. Now lets see how to implement them in java.

    How to implement shallow copy in java?

    Here is an example of Shallow Copy implementation

     1 class Subject {
     2 
     3   private String name;
     4 
     5   public String getName() {
     6     return name;
     7   }
     8 
     9   public void setName(String s) {
    10     name = s;
    11   }
    12 
    13   public Subject(String s) {
    14     name = s;
    15   }
    16 }
    17 
    18 class Student implements Cloneable {
    19   //Contained object
    20   private Subject subj;
    21 
    22   private String name;
    23 
    24   public Subject getSubj() {
    25     return subj;
    26   }
    27 
    28   public String getName() {
    29     return name;
    30   }
    31 
    32   public void setName(String s) {
    33     name = s;
    34   }
    35 
    36   public Person(String s, String sub) {
    37     name = s;
    38     subj = new Subject(sub);
    39   }
    40 
    41   public Object clone() {
    42     //shallow copy
    43     try {
    44       return super.clone();
    45     } catch (CloneNotSupportedException e) {
    46       return null;
    47     }
    48   }
    49 }
    50 
    51 public class CopyTest {
    52 
    53   public static void main(String[] args) {
    54     //Original Object
    55     Student stud = new Student("John", "Algebra");
    56 
    57     System.out.println("Original Object: " + stud.getName() + " - "
    58         + stud.getSubject().getName());
    59 
    60     //Clone Object
    61     Student clonedStud = (Student) stud.clone();
    62 
    63     System.out.println("Cloned Object: " + clonedStud.getName() + " - "
    64         + clonedStud.getSubject().getName());
    65 
    66     stud.setStudentName("Dan");
    67     stud.getSubject().setSubjectName("Physics");
    68 
    69     System.out.println("Original Object after it is updated: " 
    70         + stud.getName() + " - " + stud.getStudent().getName());
    71 
    72     System.out.println("Cloned Object after updating original object: "
    73         + clonedStud.getName() + " - " + clonedStud.getSubject().getName());
    74 
    75   }
    76 }

    Output is:
    Original Object: John - Algebra
    Cloned Object: John - Algebra
    Original Object after it is updated: Dan - Physics
    Cloned Object after updating original object: John - Physics

    In this example, all I did is, implement the class that you want to copy with Clonable interface and override clone() method of Object class and call super.clone() in it. If you observe, the changes made to "name" field of original object (Student class) is not reflected in cloned object but the changes made to "name" field of contained object (Subject class) is reflected in cloned object. This is because the cloned object carries the memory address of the Subject object but not the actual values. Hence any updates on the Subject object in Original object will reflect in Cloned object.

     

    How to implement deep copy in java?

    Here is an example of Deep Copy implementation. This is the same example of Shallow Copy implementation and hence I didnt write the Subject and CopyTest classes as there is no change in them.

     1 class Student implements Cloneable {
     2   //Contained object
     3   private Subject subj;
     4 
     5   private String name;
     6 
     7   public Subject getSubj() {
     8     return subj;
     9   }
    10 
    11   public String getName() {
    12     return name;
    13   }
    14 
    15   public void setName(String s) {
    16     name = s;
    17   }
    18 
    19   public Person(String s, String sub) {
    20     name = s;
    21     subj = new Subject(sub);
    22   }
    23 
    24   public Object clone() {
    25     //deep copy
    26     try {
    27       //Deep copy
    28       Student s = new Student(name, subj.getName());
    29       return s;
    30     } catch (CloneNotSupportedException e) {
    31       return null;
    32     }
    33   }
    34 }
     
     Output is:
     Original Object: John - Algebra
     Cloned Object: John - Algebra
     Original Object after it is updated: Dan - Physics
     Cloned Object after updating original object: Dan - Physics

     

    Well, if you observe here in the "Student" class, you will see only the change in the "clone()" method. Since its a deep copy, you need to create an object of the cloned class. Well if you have have references in the Subject class, then you need to implement Cloneable interface in Subject class and override clone method in it and this goes on and on.

    There is an alternative way for deep copy.

    Yes, there is. You can do deep copy through serialization. What does serialization do? It writes out the whole object graph into a persistant store and read it back when needed, which means you will get a copy of the whole object graph whne you read it back. This is exactly what you want when you deep copy an object. Note, when you deep copy through serialization, you should make sure that all classes in the object's graph are serializable. Let me explain you this alternative way with an example.

     1 public class ColoredCircle implements Serializable
     2 {
     3     private int x;
     4     private int y;
     5 
     6     public ColoredCircle(int x, int y){
     7         this.x = x;
     8         this.y = y;
     9     }
    10 
    11     public int getX(){
    12         return x;
    13     }
    14 
    15     public void setX(int x){
    16         this.x = x;
    17     }
    18 
    19     public int getY(){
    20         return y;
    21     }
    22 
    23     public void setX(int x){
    24         this.x = x;
    25     }
    26 }
    27 
    28 public class DeepCopy
    29 {
    30     static public void main(String[] args)
    31     {
    32         ObjectOutputStream oos = null;
    33         ObjectInputStream ois = null;
    34 
    35         try
    36         {
    37             // create original serializable object
    38             ColoredCircle c1 = new ColoredCircle(100,100);
    39             // print it
    40             System.out.println("Original = " + c1);
    41 
    42             ColoredCircle c2 = null;
    43 
    44             // deep copy
    45             ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    46             oos = new ObjectOutputStream(bos); 
    47             // serialize and pass the object
    48             oos.writeObject(c1);   
    49             oos.flush();               
    50             ByteArrayInputStream bin = 
    51                     new ByteArrayInputStream(bos.toByteArray()); 
    52             ois = new ObjectInputStream(bin);                  
    53             // return the new object
    54             c2 = ois.readObject(); 
    55 
    56             // verify it is the same
    57             System.out.println("Copied   = " + c2);
    58             // change the original object's contents
    59             c1.setX(200);
    60             c1.setY(200);
    61             // see what is in each one now
    62             System.out.println("Original = " + c1);
    63             System.out.println("Copied   = " + c2);
    64         }
    65         catch(Exception e)
    66         {
    67             System.out.println("Exception in main = " +  e);
    68         }
    69         finally
    70         {        
    71             oos.close();
    72             ois.close();
    73         }
    74     }
    75 }

     The output is:
     Original = x=100,y=100
     Copied   = x=100,y=100
     Original = x=200,y=200
     Copied   = x=100,y=100

    All you need to do here is:
    • Ensure that all classes in the object's graph are serializable.
    • Create input and output streams.
    • Use the input and output streams to create object input and object output streams.
    • Pass the object that you want to copy to the object output stream.
    • Read the new object from the object input stream and cast it back to the class of the object you sent.

    In this example, I have created a ColoredCircle object, c1 and then serialized it (write it out to ByteArrayOutputStream). Then I deserialed the serialized object and saved it in c2. Later I modified the original object, c1. Then if you see the result, c1 is different from c2. c2 is deep copy of first version of c1. So its just a copy and not a reference. Now any modifications to c1 wont affect c2, the deep copy of first version of c1.

    Well this approach has got its own limitations and issues:

    As you cannot serialize a transient variable, using this approach you cannot copy the transient variables. 
    Another issue is dealing with the case of a class whose object's instances within a virtual machine must be controlled. This is a special case of the Singleton pattern, in which a class has only one object within a VM. As discussed above, when you serialize an object, you create a totally new object that will not be unique. To get around this default behavior you can use the readResolve() method to force the stream to return an appropriate object rather than the one that was serialized. In this particular case, the appropriate object is the same one that was serialized.
    Next one is the performance issue. Creating a socket, serializing an object, passing it through the socket, and then deserializing it is slow compared to calling methods in existing objects. I say, there will be vast difference in the performance. If your code is performance critical, I suggest dont go for this approach. It takes almost 100 times more time to deep copy the object than the way you do by implementing Clonable interface.

    When to do shallow copy and deep copy?

    Its very simple that if the object has only primitive fields, then obviously you will go for shallow copy but if the object has references to other objects, then based on the requiement, shallow copy or deep copy should be chosen. What I mean here is, if the references are not modified anytime, then there is no point in going for deep copy. You can just opt shallow copy. But if the references are modified often, then you need to go for deep copy. Again there is no hard and fast rule, it all depends on the requirement.

    Finally lets have a word about rarely used option - Lazy copy

    A lazy copy is a combination of both shallow copy and deep copy. When initially copying an object, a (fast) shallow copy is used. A counter is also used to track how many objects share the data. When the program wants to modify the original object, it can determine if the data is shared (by examining the counter) and can do a deep copy at that time if necessary.

    Lazy copy looks to the outside just as a deep copy but takes advantage of the speed of a shallow copy whenever possible. It can be used when the references in the original object are not modified often. The downside are rather high but constant base costs because of the counter. Also, in certain situations, circular references can also cause problems.

    posted on 2012-04-07 18:41 gembin 閱讀(842) 評論(0)  編輯  收藏 所屬分類: JavaSE

    導航

    統計

    常用鏈接

    留言簿(6)

    隨筆分類(440)

    隨筆檔案(378)

    文章檔案(6)

    新聞檔案(1)

    相冊

    收藏夾(9)

    Adobe

    Android

    AS3

    Blog-Links

    Build

    Design Pattern

    Eclipse

    Favorite Links

    Flickr

    Game Dev

    HBase

    Identity Management

    IT resources

    JEE

    Language

    OpenID

    OSGi

    SOA

    Version Control

    最新隨筆

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    free counters
    主站蜘蛛池模板: 国产精品成人免费综合| a在线观看免费视频| 91在线品视觉盛宴免费| 亚洲国产成人精品无码区在线观看 | 亚洲日韩一区二区三区| 国产成人免费午夜在线观看| 亚洲AV无码久久精品成人 | 一出一进一爽一粗一大视频免费的| 日韩伦理片电影在线免费观看| 亚洲 欧洲 自拍 另类 校园| 最近中文字幕免费mv在线视频| 亚洲一区二区在线免费观看| 4444www免费看| 亚洲经典千人经典日产| 国产乱子伦精品免费无码专区| 免费激情网站国产高清第一页 | 亚洲国产成人私人影院| 久久久久国产精品免费免费不卡| 亚洲综合婷婷久久| 两个人的视频高清在线观看免费| ASS亚洲熟妇毛茸茸PICS| 午夜一区二区免费视频| 国产亚洲日韩在线a不卡| 国产成人亚洲精品91专区手机| 久久精品无码免费不卡| 亚洲av伊人久久综合密臀性色| 亚洲一级毛片免费观看| 亚洲av无一区二区三区| 国产成人精品久久亚洲高清不卡 | 久久99热精品免费观看牛牛| 亚洲ts人妖网站| 亚洲国产香蕉人人爽成AV片久久 | 亚洲人成网站在线播放2019| 国产一级淫片a视频免费观看| 成人A毛片免费观看网站| 亚洲精品中文字幕无码AV| 在线观看免费亚洲| 国产一区二区免费视频| 亚洲真人无码永久在线观看| 中文字幕亚洲乱码熟女一区二区 | 深夜A级毛片视频免费|