亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Java深拷貝和淺拷貝

wangshijun / 1057人閱讀

摘要:中有三種類型的對(duì)象拷貝淺拷貝深拷貝延遲拷貝。深拷貝相比于淺拷貝速度較慢并且花銷較大。意思是如果對(duì)象引用任何時(shí)候都不會(huì)被改變,那么沒(méi)必要使用深拷貝,只需要使用淺拷貝就行了。

目錄介紹

01.對(duì)象拷貝有哪些

02.理解淺拷貝

2.1 什么是淺拷貝

2.2 實(shí)現(xiàn)淺拷貝案例

03.理解深拷貝

3.1 什么是深拷貝

3.2 實(shí)現(xiàn)深拷貝案例

04.序列化進(jìn)行拷貝

4.1 序列化屬于深拷貝

4.2 注意要點(diǎn)

4.3 序列化案例

05.延遲拷貝

06.如何選擇拷貝方式

07.數(shù)組的拷貝

7.1 基本數(shù)據(jù)類型數(shù)組

7.2 引用數(shù)據(jù)類型數(shù)組

08.集合的拷貝

8.1 集合淺拷貝

8.2 集合深拷貝

好消息

博客筆記大匯總【16年3月到至今】,包括Java基礎(chǔ)及深入知識(shí)點(diǎn),Android技術(shù)博客,Python學(xué)習(xí)筆記等等,還包括平時(shí)開發(fā)中遇到的bug匯總,當(dāng)然也在工作之余收集了大量的面試題,長(zhǎng)期更新維護(hù)并且修正,持續(xù)完善……開源的文件是markdown格式的!同時(shí)也開源了生活博客,從12年起,積累共計(jì)N篇[近100萬(wàn)字,陸續(xù)搬到網(wǎng)上],轉(zhuǎn)載請(qǐng)注明出處,謝謝!

鏈接地址:https://github.com/yangchong2...

如果覺得好,可以star一下,謝謝!當(dāng)然也歡迎提出建議,萬(wàn)事起于忽微,量變引起質(zhì)變!

01.對(duì)象拷貝有哪些

對(duì)象拷貝(Object Copy)就是將一個(gè)對(duì)象的屬性拷貝到另一個(gè)有著相同類類型的對(duì)象中去。在程序中拷貝對(duì)象是很常見的,主要是為了在新的上下文環(huán)境中復(fù)用對(duì)象的部分或全部數(shù)據(jù)。

Java中有三種類型的對(duì)象拷貝:淺拷貝(Shallow Copy)、深拷貝(Deep Copy)、延遲拷貝(Lazy Copy)。

02.理解淺拷貝 2.1 什么是淺拷貝

淺拷貝是按位拷貝對(duì)象,它會(huì)創(chuàng)建一個(gè)新對(duì)象,這個(gè)對(duì)象有著原始對(duì)象屬性值的一份精確拷貝。

如果屬性是基本類型,拷貝的就是基本類型的值;如果屬性是內(nèi)存地址(引用類型),拷貝的就是內(nèi)存地址 ,因此如果其中一個(gè)對(duì)象改變了這個(gè)地址,就會(huì)影響到另一個(gè)對(duì)象。

在上圖中,SourceObject有一個(gè)int類型的屬性 "field1"和一個(gè)引用類型屬性"refObj"(引用ContainedObject類型的對(duì)象)。當(dāng)對(duì)SourceObject做淺拷貝時(shí),創(chuàng)建了CopiedObject,它有一個(gè)包含"field1"拷貝值的屬性"field2"以及仍指向refObj本身的引用。由于"field1"是基本類型,所以只是將它的值拷貝給"field2",但是由于"refObj"是一個(gè)引用類型, 所以CopiedObject指向"refObj"相同的地址。因此對(duì)SourceObject中的"refObj"所做的任何改變都會(huì)影響到CopiedObject。

2.2 如何實(shí)現(xiàn)淺拷貝

下面來(lái)看一看實(shí)現(xiàn)淺拷貝的一個(gè)例子

public class Subject {
 
   private String name; 
   public Subject(String s) { 
      name = s; 
   } 

   public String getName() { 
      return name; 
   } 

   public void setName(String s) { 
      name = s; 
   } 
}
public class Student implements Cloneable { 
 
   // 對(duì)象引用 
   private Subject subj; 
   private String name; 
 
   public Student(String s, String sub) { 
      name = s; 
      subj = new Subject(sub); 
   } 
 
   public Subject getSubj() { 
      return subj; 
   } 
 
   public String getName() { 
      return name; 
   } 
 
   public void setName(String s) { 
      name = s; 
   } 
 
   /** 
    *  重寫clone()方法 

    */ 
   public Object clone() { 
      //淺拷貝 
      try { 
         // 直接調(diào)用父類的clone()方法
         return super.clone(); 
      } catch (CloneNotSupportedException e) { 
         return null; 
      } 
   } 
}
```

```
private void test1(){
    // 原始對(duì)象
    Student stud = new Student("楊充", "瀟湘劍雨");
    System.out.println("原始對(duì)象: " + stud.getName() + " - " + stud.getSubj().getName());

    // 拷貝對(duì)象
    Student clonedStud = (Student) stud.clone();
    System.out.println("拷貝對(duì)象: " + clonedStud.getName() + " - " + clonedStud.getSubj().getName());

    // 原始對(duì)象和拷貝對(duì)象是否一樣:
    System.out.println("原始對(duì)象和拷貝對(duì)象是否一樣: " + (stud == clonedStud));
    // 原始對(duì)象和拷貝對(duì)象的name屬性是否一樣
    System.out.println("原始對(duì)象和拷貝對(duì)象的name屬性是否一樣: " + (stud.getName() == clonedStud.getName()));
    // 原始對(duì)象和拷貝對(duì)象的subj屬性是否一樣
    System.out.println("原始對(duì)象和拷貝對(duì)象的subj屬性是否一樣: " + (stud.getSubj() == clonedStud.getSubj()));

    stud.setName("小楊逗比");
    stud.getSubj().setName("瀟湘劍雨大俠");
    System.out.println("更新后的原始對(duì)象: " + stud.getName() + " - " + stud.getSubj().getName());
    System.out.println("更新原始對(duì)象后的克隆對(duì)象: " + clonedStud.getName() + " - " + clonedStud.getSubj().getName());
}
```

輸出結(jié)果如下:

2019-03-23 13:50:57.518 24704-24704/com.ycbjie.other I/System.out: 原始對(duì)象: 楊充 - 瀟湘劍雨
2019-03-23 13:50:57.519 24704-24704/com.ycbjie.other I/System.out: 拷貝對(duì)象: 楊充 - 瀟湘劍雨
2019-03-23 13:50:57.519 24704-24704/com.ycbjie.other I/System.out: 原始對(duì)象和拷貝對(duì)象是否一樣: false
2019-03-23 13:50:57.519 24704-24704/com.ycbjie.other I/System.out: 原始對(duì)象和拷貝對(duì)象的name屬性是否一樣: true
2019-03-23 13:50:57.519 24704-24704/com.ycbjie.other I/System.out: 原始對(duì)象和拷貝對(duì)象的subj屬性是否一樣: true
2019-03-23 13:50:57.519 24704-24704/com.ycbjie.other I/System.out: 更新后的原始對(duì)象: 小楊逗比 - 瀟湘劍雨大俠
2019-03-23 13:50:57.519 24704-24704/com.ycbjie.other I/System.out: 更新原始對(duì)象后的克隆對(duì)象: 楊充 - 瀟湘劍雨大俠

可以得出的結(jié)論

在這個(gè)例子中,讓要拷貝的類Student實(shí)現(xiàn)了Clonable接口并重寫Object類的clone()方法,然后在方法內(nèi)部調(diào)用super.clone()方法。從輸出結(jié)果中我們可以看到,對(duì)原始對(duì)象stud的"name"屬性所做的改變并沒(méi)有影響到拷貝對(duì)象clonedStud,但是對(duì)引用對(duì)象subj的"name"屬性所做的改變影響到了拷貝對(duì)象clonedStud。

03.理解深拷貝 3.1 什么是深拷貝

深拷貝會(huì)拷貝所有的屬性,并拷貝屬性指向的動(dòng)態(tài)分配的內(nèi)存。當(dāng)對(duì)象和它所引用的對(duì)象一起拷貝時(shí)即發(fā)生深拷貝。深拷貝相比于淺拷貝速度較慢并且花銷較大。

在上圖中,SourceObject有一個(gè)int類型的屬性 "field1"和一個(gè)引用類型屬性"refObj1"(引用ContainedObject類型的對(duì)象)。當(dāng)對(duì)SourceObject做深拷貝時(shí),創(chuàng)建了CopiedObject,它有一個(gè)包含"field1"拷貝值的屬性"field2"以及包含"refObj1"拷貝值的引用類型屬性"refObj2" 。因此對(duì)SourceObject中的"refObj"所做的任何改變都不會(huì)影響到CopiedObject

3.2 實(shí)現(xiàn)深拷貝案例

下面是實(shí)現(xiàn)深拷貝的一個(gè)例子。只是在淺拷貝的例子上做了一點(diǎn)小改動(dòng),Subject 和CopyTest 類都沒(méi)有變化。

public class Student implements Cloneable { 
   // 對(duì)象引用 
   private Subject subj; 
   private String name; 
 
   public Student(String s, String sub) { 
      name = s; 
      subj = new Subject(sub); 
   } 
 
   public Subject getSubj() { 
      return subj; 
   } 
 
   public String getName() { 
      return name; 
   } 
 
   public void setName(String s) { 
      name = s; 
   } 
 
   /** 
    * 重寫clone()方法 
    * 

    */ 
   public Object clone() { 
      // 深拷貝,創(chuàng)建拷貝類的一個(gè)新對(duì)象,這樣就和原始對(duì)象相互獨(dú)立
      Student s = new Student(name, subj.getName()); 
      return s; 
   } 
}
```

輸出結(jié)果如下:

2019-03-23 13:53:48.096 25123-25123/com.ycbjie.other I/System.out: 原始對(duì)象: 楊充 - 瀟湘劍雨
2019-03-23 13:53:48.096 25123-25123/com.ycbjie.other I/System.out: 拷貝對(duì)象: 楊充 - 瀟湘劍雨
2019-03-23 13:53:48.096 25123-25123/com.ycbjie.other I/System.out: 原始對(duì)象和拷貝對(duì)象是否一樣: false
2019-03-23 13:53:48.096 25123-25123/com.ycbjie.other I/System.out: 原始對(duì)象和拷貝對(duì)象的name屬性是否一樣: true
2019-03-23 13:53:48.096 25123-25123/com.ycbjie.other I/System.out: 原始對(duì)象和拷貝對(duì)象的subj屬性是否一樣: false
2019-03-23 13:53:48.096 25123-25123/com.ycbjie.other I/System.out: 更新后的原始對(duì)象: 小楊逗比 - 瀟湘劍雨大俠
2019-03-23 13:53:48.096 25123-25123/com.ycbjie.other I/System.out: 更新原始對(duì)象后的克隆對(duì)象: 楊充 - 瀟湘劍雨

得出的結(jié)論

很容易發(fā)現(xiàn)clone()方法中的一點(diǎn)變化。因?yàn)樗巧羁截?,所以你需要?jiǎng)?chuàng)建拷貝類的一個(gè)對(duì)象。因?yàn)樵赟tudent類中有對(duì)象引用,所以需要在Student類中實(shí)現(xiàn)Cloneable接口并且重寫clone方法。

04.序列化進(jìn)行拷貝 4.1 序列化屬于深拷貝

可能你會(huì)問(wèn),序列化是屬于那種類型拷貝?答案是:通過(guò)序列化來(lái)實(shí)現(xiàn)深拷貝??梢运伎家幌拢瑸楹涡蛄谢瘜?duì)象要用深拷貝而不是用淺拷貝呢?

4.2 注意要點(diǎn)

可以序列化是干什么的?它將整個(gè)對(duì)象圖寫入到一個(gè)持久化存儲(chǔ)文件中并且當(dāng)需要的時(shí)候把它讀取回來(lái), 這意味著當(dāng)你需要把它讀取回來(lái)時(shí)你需要整個(gè)對(duì)象圖的一個(gè)拷貝。這就是當(dāng)你深拷貝一個(gè)對(duì)象時(shí)真正需要的東西。請(qǐng)注意,當(dāng)你通過(guò)序列化進(jìn)行深拷貝時(shí),必須確保對(duì)象圖中所有類都是可序列化的。

4.3 序列化案例

看一下下面案例,很簡(jiǎn)單,只需要實(shí)現(xiàn)Serializable這個(gè)接口。Android中還可以實(shí)現(xiàn)Parcelable接口。

public class ColoredCircle implements Serializable { 
 
   private int x; 
   private int y; 
 
   public ColoredCircle(int x, int y) { 
      this.x = x; 
      this.y = y; 
   } 
 
   public int getX() { 
      return x; 
   } 
 
   public void setX(int x) { 
      this.x = x; 
   } 
 
   public int getY() { 
      return y; 
   } 
 
   public void setY(int y) { 
      this.y = y; 
   } 
 
   @Override 
   public String toString() { 
      return "x=" + x + ", y=" + y; 
   } 
}
private void test3() {
    ObjectOutputStream oos = null;
    ObjectInputStream ois = null;
    try {
        // 創(chuàng)建原始的可序列化對(duì)象
        DouBi c1 = new DouBi(100, 100);
        System.out.println("原始的對(duì)象 = " + c1);
        DouBi c2 = null;
        // 通過(guò)序列化實(shí)現(xiàn)深拷貝
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        oos = new ObjectOutputStream(bos);
        // 序列化以及傳遞這個(gè)對(duì)象
        oos.writeObject(c1);
        oos.flush();
        ByteArrayInputStream bin = new ByteArrayInputStream(bos.toByteArray());
        ois = new ObjectInputStream(bin);
        // 返回新的對(duì)象
        c2 = (DouBi) ois.readObject();
        // 校驗(yàn)內(nèi)容是否相同
        System.out.println("復(fù)制后的對(duì)象   = " + c2);
        // 改變?cè)紝?duì)象的內(nèi)容
        c1.setX(200);
        c1.setY(200);
        // 查看每一個(gè)現(xiàn)在的內(nèi)容
        System.out.println("查看原始的對(duì)象 = " + c1);
        System.out.println("查看復(fù)制的對(duì)象 = " + c2);
    } catch (IOException e) {
        System.out.println("Exception in main = " + e);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (oos != null) {
            try {
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (ois != null) {
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

輸出結(jié)果如下:

2019-03-23 13:53:48.096 25123-25123/com.ycbjie.other I/System.out: 原始的對(duì)象 = x=100, y=100
2019-03-23 13:53:48.096 25123-25123/com.ycbjie.other I/System.out: 復(fù)制后的對(duì)象   = x=100, y=100
2019-03-23 13:53:48.096 25123-25123/com.ycbjie.other I/System.out: 查看原始的對(duì)象 = x=200, y=200
2019-03-23 13:53:48.096 25123-25123/com.ycbjie.other I/System.out: 查看復(fù)制的對(duì)象   = x=100, y=100

注意:需要做以下幾件事兒:

確保對(duì)象圖中的所有類都是可序列化的

創(chuàng)建輸入輸出流

使用這個(gè)輸入輸出流來(lái)創(chuàng)建對(duì)象輸入和對(duì)象輸出流

將你想要拷貝的對(duì)象傳遞給對(duì)象輸出流

從對(duì)象輸入流中讀取新的對(duì)象并且轉(zhuǎn)換回你所發(fā)送的對(duì)象的類

得出的結(jié)論

在這個(gè)例子中,創(chuàng)建了一個(gè)DouBi對(duì)象c1然后將它序列化 (將它寫到ByteArrayOutputStream中). 然后我反序列化這個(gè)序列化后的對(duì)象并將它保存到c2中。隨后我修改了原始對(duì)象c1。然后結(jié)果如你所見,c1不同于c2,對(duì)c1所做的任何修改都不會(huì)影響c2。

注意,序列化這種方式有其自身的限制和問(wèn)題:因?yàn)闊o(wú)法序列化transient變量, 使用這種方法將無(wú)法拷貝transient變量。再就是性能問(wèn)題。創(chuàng)建一個(gè)socket, 序列化一個(gè)對(duì)象, 通過(guò)socket傳輸它, 然后反序列化它,這個(gè)過(guò)程與調(diào)用已有對(duì)象的方法相比是很慢的。所以在性能上會(huì)有天壤之別。如果性能對(duì)你的代碼來(lái)說(shuō)是至關(guān)重要的,建議不要使用這種方式。它比通過(guò)實(shí)現(xiàn)Clonable接口這種方式來(lái)進(jìn)行深拷貝幾乎多花100倍的時(shí)間。

05.延遲拷貝

延遲拷貝是淺拷貝和深拷貝的一個(gè)組合,實(shí)際上很少會(huì)使用。這個(gè)以前幾乎都沒(méi)聽說(shuō)過(guò),后來(lái)看書才知道有這么一種拷貝!

當(dāng)最開始拷貝一個(gè)對(duì)象時(shí),會(huì)使用速度較快的淺拷貝,還會(huì)使用一個(gè)計(jì)數(shù)器來(lái)記錄有多少對(duì)象共享這個(gè)數(shù)據(jù)。當(dāng)程序想要修改原始的對(duì)象時(shí),它會(huì)決定數(shù)據(jù)是否被共享(通過(guò)檢查計(jì)數(shù)器)并根據(jù)需要進(jìn)行深拷貝。

延遲拷貝從外面看起來(lái)就是深拷貝,但是只要有可能它就會(huì)利用淺拷貝的速度。當(dāng)原始對(duì)象中的引用不經(jīng)常改變的時(shí)候可以使用延遲拷貝。由于存在計(jì)數(shù)器,效率下降很高,但只是常量級(jí)的開銷。而且, 在某些情況下, 循環(huán)引用會(huì)導(dǎo)致一些問(wèn)題。

06.如何選擇拷貝方式

如果對(duì)象的屬性全是基本類型的,那么可以使用淺拷貝。

如果對(duì)象有引用屬性,那就要基于具體的需求來(lái)選擇淺拷貝還是深拷貝。

意思是如果對(duì)象引用任何時(shí)候都不會(huì)被改變,那么沒(méi)必要使用深拷貝,只需要使用淺拷貝就行了。如果對(duì)象引用經(jīng)常改變,那么就要使用深拷貝。沒(méi)有一成不變的規(guī)則,一切都取決于具體需求。

07.數(shù)組的拷貝

數(shù)組除了默認(rèn)實(shí)現(xiàn)了clone()方法之外,還提供了Arrays.copyOf方法用于拷貝,這兩者都是淺拷貝。

7.1 基本數(shù)據(jù)類型數(shù)組

如下所示

public void test4() {
    int[] lNumbers1 = new int[5];
    int[] rNumbers1 = Arrays.copyOf(lNumbers1, lNumbers1.length);
    rNumbers1[0] = 1;
    boolean first = lNumbers1[0] == rNumbers1[0];
    Log.d("小楊逗比", "lNumbers2[0]=" + lNumbers1[0] + ",rNumbers2[0]=" + rNumbers1[0]+"---"+first);

    int[] lNumbers3 = new int[5];
    int[] rNumbers3 = lNumbers3.clone();
    rNumbers3[0] = 1;
    boolean second = lNumbers3[0] == rNumbers3[0];
    Log.d("小楊逗比", "lNumbers3[0]=" + lNumbers3[0] + ",rNumbers3[0]=" + rNumbers3[0]+"---"+second);
}

打印結(jié)果如下所示

2019-03-25 14:28:09.907 30316-30316/org.yczbj.ycrefreshview D/小楊逗比: lNumbers2[0]=0,rNumbers2[0]=1---false
2019-03-25 14:28:09.907 30316-30316/org.yczbj.ycrefreshview D/小楊逗比: lNumbers3[0]=0,rNumbers3[0]=1---false

7.2 引用數(shù)據(jù)類型數(shù)組

如下所示

public static void test5() {
    People[] lNumbers1 = new People[5];
    lNumbers1[0] = new People();
    People[] rNumbers1 = lNumbers1;
    boolean first = lNumbers1[0].equals(rNumbers1[0]);
    Log.d("小楊逗比", "lNumbers1[0]=" + lNumbers1[0] + ",rNumbers1[0]=" + rNumbers1[0]+"--"+first);

    People[] lNumbers2 = new People[5];
    lNumbers2[0] = new People();
    People[] rNumbers2 = Arrays.copyOf(lNumbers2, lNumbers2.length);
    boolean second = lNumbers2[0].equals(rNumbers2[0]);
    Log.d("小楊逗比", "lNumbers2[0]=" + lNumbers2[0] + ",rNumbers2[0]=" + rNumbers2[0]+"--"+second);

    People[] lNumbers3 = new People[5];
    lNumbers3[0] = new People();
    People[] rNumbers3 = lNumbers3.clone();
    boolean third = lNumbers3[0].equals(rNumbers3[0]);
    Log.d("小楊逗比", "lNumbers3[0]=" + lNumbers3[0] + ",rNumbers3[0]=" + rNumbers3[0]+"--"+third);
}

public static class People implements Cloneable {

    int age;
    Holder holder;

    @Override
    protected Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static class Holder {
        int holderValue;
    }
}

打印日志如下

2019-03-25 14:53:17.054 31093-31093/org.yczbj.ycrefreshview D/小楊逗比: lNumbers1[0]=org.yczbj.ycrefreshview.MainActivity$People@46a2c18,rNumbers1[0]=org.yczbj.ycrefreshview.MainActivity$People@46a2c18--true
2019-03-25 14:53:17.054 31093-31093/org.yczbj.ycrefreshview D/小楊逗比: lNumbers2[0]=org.yczbj.ycrefreshview.MainActivity$People@d344671,rNumbers2[0]=org.yczbj.ycrefreshview.MainActivity$People@d344671--true
2019-03-25 14:53:17.054 31093-31093/org.yczbj.ycrefreshview D/小楊逗比: lNumbers3[0]=org.yczbj.ycrefreshview.MainActivity$People@91e9c56,rNumbers3[0]=org.yczbj.ycrefreshview.MainActivity$People@91e9c56--true

08.集合的拷貝

集合的拷貝也是我們平時(shí)經(jīng)常會(huì)遇到的,一般情況下,我們都是用淺拷貝來(lái)實(shí)現(xiàn),即通過(guò)構(gòu)造函數(shù)或者clone方法。

8.1 集合淺拷貝

構(gòu)造函數(shù)和 clone() 默認(rèn)都是淺拷貝

public static void test6() {
    ArrayList lPeoples = new ArrayList<>();
    People people1 = new People();
    lPeoples.add(people1);
    Log.d("小楊逗比", "lPeoples[0]=" + lPeoples.get(0));
    ArrayList rPeoples = (ArrayList) lPeoples.clone();
    Log.d("小楊逗比", "rPeoples[0]=" + rPeoples.get(0));
    boolean b = lPeoples.get(0).equals(rPeoples.get(0));
    Log.d("小楊逗比", "比較兩個(gè)對(duì)象" + b);
}

public static class People implements Cloneable {

    int age;
    Holder holder;

    @Override
    protected Object clone() {
        try {
            People people = (People) super.clone();
            people.holder = (People.Holder) this.holder.clone();
            return people;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static class Holder implements Cloneable {

        int holderValue;

        @Override
        protected Object clone() {
            try {
                return super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
}

打印日志

2019-03-25 14:56:56.931 31454-31454/org.yczbj.ycrefreshview D/小楊逗比: lPeoples[0]=org.yczbj.ycrefreshview.MainActivity$People@46a2c18
2019-03-25 14:56:56.931 31454-31454/org.yczbj.ycrefreshview D/小楊逗比: rPeoples[0]=org.yczbj.ycrefreshview.MainActivity$People@46a2c18
2019-03-25 14:56:56.931 31454-31454/org.yczbj.ycrefreshview D/小楊逗比: 比較兩個(gè)對(duì)象true

8.2 集合深拷貝

在某些特殊情況下,如果需要實(shí)現(xiàn)集合的深拷貝,那就要?jiǎng)?chuàng)建一個(gè)新的集合,然后通過(guò)深拷貝原先集合中的每個(gè)元素,將這些元素加入到新的集合當(dāng)中。

public static void test7() {
    ArrayList lPeoples = new ArrayList<>();
    People people1 = new People();
    people1.holder = new People.Holder();
    lPeoples.add(people1);
    Log.d("小楊逗比", "lPeoples[0]=" + lPeoples.get(0));
    ArrayList rPeoples = new ArrayList<>();
    for (People people : lPeoples) {
        rPeoples.add((People) people.clone());
    }
    Log.d("小楊逗比", "rPeoples[0]=" + rPeoples.get(0));
    boolean b = lPeoples.get(0).equals(rPeoples.get(0));
    Log.d("小楊逗比", "比較兩個(gè)對(duì)象" + b);
}

public static class People implements Cloneable {

    int age;
    Holder holder;

    @Override
    protected Object clone() {
        try {
            People people = (People) super.clone();
            people.holder = (People.Holder) this.holder.clone();
            return people;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static class Holder implements Cloneable {

        int holderValue;

        @Override
        protected Object clone() {
            try {
                return super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
}

打印日志

2019-03-25 15:00:54.610 31670-31670/org.yczbj.ycrefreshview D/小楊逗比: lPeoples[0]=org.yczbj.ycrefreshview.MainActivity$People@46a2c18
2019-03-25 15:00:54.610 31670-31670/org.yczbj.ycrefreshview D/小楊逗比: rPeoples[0]=org.yczbj.ycrefreshview.MainActivity$People@d344671
2019-03-25 15:00:54.610 31670-31670/org.yczbj.ycrefreshview D/小楊逗比: 比較兩個(gè)對(duì)象false

其他介紹 01.關(guān)于博客匯總鏈接

1.技術(shù)博客匯總

2.開源項(xiàng)目匯總

3.生活博客匯總

4.喜馬拉雅音頻匯總

5.其他匯總

02.關(guān)于我的博客

我的個(gè)人站點(diǎn):www.yczbj.org,www.ycbjie.cn

github:https://github.com/yangchong211

知乎:https://www.zhihu.com/people/...

簡(jiǎn)書:http://www.jianshu.com/u/b7b2...

csdn:http://my.csdn.net/m0_37700275

喜馬拉雅聽書:http://www.ximalaya.com/zhubo...

開源中國(guó):https://my.oschina.net/zbj161...

泡在網(wǎng)上的日子:http://www.jcodecraeer.com/me...

郵箱:yangchong211@163.com

阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV

segmentfault頭條:https://segmentfault.com/u/xi...

掘金:https://juejin.im/user/593943...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/73911.html

相關(guān)文章

  • JS里拷貝和淺拷貝的釋義

    摘要:本文解釋中深拷貝和淺拷貝的區(qū)別。深拷貝深拷貝指遞歸的復(fù)制對(duì)象的屬性給新對(duì)象。有些時(shí)候一層的深拷貝被認(rèn)為是淺拷貝,比如的值是一個(gè)對(duì)象,淺拷貝出來(lái)的新對(duì)象直接引用了原對(duì)象的對(duì)象,所以也會(huì)相互影響的。 本文解釋javascript中深拷貝和淺拷貝的區(qū)別。 淺拷貝/Shallow Copy 淺拷貝指拷貝了引用值。 var original = {prop1 : Prop1, prop2 : p...

    zollero 評(píng)論0 收藏0
  • 拷貝和淺拷貝的區(qū)別

    摘要:深拷貝和淺拷貝的區(qū)別背景最近在用框架寫頁(yè)面,賦值給中的對(duì)象時(shí)會(huì)出現(xiàn)一個(gè)問(wèn)題,賦值和被賦值對(duì)象之中任何一個(gè)有變化,另一個(gè)也會(huì)隨之變化。 深拷貝和淺拷貝的區(qū)別 背景:最近在用vue框架寫頁(yè)面,賦值給Vue.$data中的對(duì)象時(shí)會(huì)出現(xiàn)一個(gè)問(wèn)題,賦值和被賦值對(duì)象之中任何一個(gè)有變化,另一個(gè)也會(huì)隨之變化。例如: var b = { foo: 123 }; var vm = new Vue(...

    suemi 評(píng)論0 收藏0
  • js拷貝和淺拷貝

    摘要:深拷貝和淺拷貝深拷貝和淺拷貝的示意圖大致如下淺拷貝只復(fù)制指向某個(gè)對(duì)象的指針,而不復(fù)制對(duì)象本身,新舊對(duì)象還是共享同一塊內(nèi)存。參考文章什么是深拷貝和淺拷貝及其實(shí)現(xiàn)方式 走在前端的大道上 本篇將自己讀過(guò)的相關(guān)文章中,對(duì)自己有啟發(fā)的章節(jié)片段總結(jié)在這(會(huì)對(duì)原文進(jìn)行刪改),會(huì)不斷豐富提煉總結(jié)更新。 淺拷貝 var m = { a: 10, b: 20 } var n = m; n.a = 15; ...

    MAX_zuo 評(píng)論0 收藏0
  • 對(duì)拷貝和淺拷貝的全面理解

    摘要:關(guān)于深拷貝和淺拷貝從原理看淺拷貝拷貝一層,對(duì)象級(jí)別的則拷貝引用深拷貝拷貝多層,每個(gè)層級(jí)的屬性都會(huì)拷貝從現(xiàn)象看復(fù)制了,被修改后,隨變化而變化淺拷貝不變深拷貝深拷貝針對(duì)的復(fù)雜的類型數(shù)據(jù)如直接賦值的單層拷貝,如,雖然不受的影響,但是這也不算做 關(guān)于深拷貝和淺拷貝 從原理看: 淺拷貝:拷貝一層,對(duì)象級(jí)別的則拷貝引用 深拷貝:拷貝多層,每個(gè)層級(jí)的屬性都會(huì)拷貝 從現(xiàn)象看:A復(fù)制了B,B被修改后...

    _DangJin 評(píng)論0 收藏0
  • 探索php和python下對(duì)象的拷貝和淺拷貝

    摘要:對(duì)于而言,情況可能會(huì)有點(diǎn)小復(fù)雜,因?yàn)橐磺薪詾閷?duì)象,所以的普通賦值深拷貝和淺拷貝之間都是有細(xì)微區(qū)別的。二下的他們?cè)谥校瑢?duì)象的賦值和傳遞都是引用。 一、深拷貝與淺拷貝 ??深拷貝:賦值時(shí)值完全復(fù)制,完全的copy,對(duì)其中一個(gè)作出改變,不會(huì)影響另一個(gè) ??淺拷貝:賦值時(shí),引用賦值,相當(dāng)于取了一個(gè)別名。對(duì)其中一個(gè)修改,會(huì)影響另一個(gè) ??對(duì)于PHP而言,= 賦值時(shí),普通對(duì)象是深拷貝,但對(duì)對(duì)象來(lái)說(shuō)...

    shinezejian 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<