天天看點

Java集合引用傳遞問題(集合的淺複制和深複制)

淺複制

實體類

package com.ahut.entity;

import java.io.Serializable;
import java.util.Date;

/**
 * 
 * @ClassName: Demo
 * @Description:
 * @author cheng
 * @date
public class Demo implements Serializable

    /**
     * 序列化
     */
    private static final long serialVersionUID = 4122974131420281791L;

    private String id;

    private String userName;

    private int age;

    private Date birthDay;

    public Demo() {
        super();
        // TODO Auto-generated constructor stub
    }

    @Override
    public String toString() {
        return "Demo [birthDay=" + birthDay + ", userName=" + userName + ", age=" + age + ", id=" + id + "]";
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

}      

集合測試

/**
     * 
     * @Title: testCollection
     * @Description:
     */
    @Test
    public void testCollection(){
        // 建立元素1
        Demo demo1 = new Demo();
        demo1.setId("1234");
        demo1.setUserName("demo1");
        demo1.setAge(20);
        demo1.setBirthDay(new Date());

        // 建立元素2
        Demo demo2 = new Demo();
        demo2.setId("5678");
        demo2.setUserName("demo2");
        demo2.setAge(40);
        demo2.setBirthDay(new Date());

        // 将元素添加到list1中
        List<Demo> demoList1 = new ArrayList<>();
        demoList1.add(demo1);
        demoList1.add(demo2);

        // 使用list1作為參數,建立list2
        List<Demo> demoList2 = new ArrayList<>(demoList1);
        System.out.println("demoList1====================================");
        for(Demo demo : demoList1){
            System.out.println(demo);
        }
        System.out.println("demoList2====================================");
        for(Demo demo : demoList2){
            System.out.println(demo);
        }

        輸出如下:
        demoList1====================================
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo1, age=20, id=1234]
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo2, age=40, id=5678]
        demoList2====================================
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo1, age=20, id=1234]
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo2, age=40, id=5678]

        // 取出list2中的元素并修改其屬性,發現list1中的元素也發生了改變
        Demo demo3 = demoList2.get(0);
        demo3.setAge(9999);
        System.out.println("demoList1====================================");
        for(Demo demo : demoList1){
            System.out.println(demo);
        }
        System.out.println("demoList2====================================");
        for(Demo demo : demoList2){
            System.out.println(demo);
        }

        輸出如下:
        demoList1====================================
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo1, age=9999, id=1234]
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo2, age=40, id=5678]
        demoList2====================================
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo1, age=9999, id=1234]
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo2, age=40, id=5678]

        // 删除list2中的元素,list1不發生改變
        demoList2.remove(0);
        System.out.println("demoList1====================================");
        for(Demo demo : demoList1){
            System.out.println(demo);
        }
        System.out.println("demoList2====================================");
        for(Demo demo : demoList2){
            System.out.println(demo);
        }

        輸出結果:
        demoList1====================================
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo1, age=9999, id=1234]
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo2, age=40, id=5678]
        demoList2====================================
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo2, age=40, id=5678]

        // 取出list2中剩下的元素并修改其屬性,發現list1中的元素也發生了改變
        Demo demo4 = demoList2.get(0);
        demo4.setAge(6666);
        System.out.println("demoList1====================================");
        for(Demo demo : demoList1){
            System.out.println(demo);
        }
        System.out.println("demoList2====================================");
        for(Demo demo : demoList2){
            System.out.println(demo);
        }

        輸出結果:
        demoList1====================================
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo1, age=9999, id=1234]
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo2, age=6666, id=5678]
        demoList2====================================
        Demo [birthDay=Tue Jan 09 14:29:21 CST 2018, userName=demo2, age=6666, id=5678]
    }      

記憶體分析

Java集合引用傳遞問題(集合的淺複制和深複制)

拷貝list中的對象是一緻的,而list是2個對象

改變其中一個list,另一個list不改變

改變list内的一個對象,另一個也改變

List中ArrayList的本質還是數組,本質上差別在于是同一個數組,還是不同的數組。對于其中的對象存儲的都是執行個體的位址,改變影響在所難免。

深複制

實體類

實作Cloneable 接口,重寫clone方法

package com.ahut.entity;

import java.io.Serializable;
import java.util.Date;

/**
 * 
 * @ClassName: Demo
 * @Description:
 * @author cheng
 * @date
public class Demo implements Serializable,Cloneable

    /**
     * 序列化
     */
    private static final long serialVersionUID = 4122974131420281791L;

    private String id;

    private String userName;

    private int age;

    private Date birthDay;

    public Demo() {
        super();
        // TODO Auto-generated constructor stub
    }

    @Override
    public String toString() {
        return "Demo [birthDay=" + birthDay + ", userName=" + userName + ", age=" + age + ", id=" + id + "]";
    }

    /**
     * 重寫clone方法
     */
    @Override
    public Demo clone() throws CloneNotSupportedException {
        return (Demo)super.clone();
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

}      

集合測試

/**
     * 
     * @throws CloneNotSupportedException 
     * @Title: testCollection
     * @Description:
     */
    @Test
    public void testCollection() throws CloneNotSupportedException{
        Demo demo1 = new Demo();
        demo1.setId("1234");
        demo1.setUserName("demo1");
        demo1.setAge(20);
        demo1.setBirthDay(new Date());

        Demo demo2 = new Demo();
        demo2.setId("5678");
        demo2.setUserName("demo2");
        demo2.setAge(40);
        demo2.setBirthDay(new Date());

        List<Demo> demoList1 = new ArrayList<>();
        demoList1.add(demo1);
        demoList1.add(demo2);

        // 集合深複制
        List<Demo> demoList2 = new ArrayList<>();
        for(Demo demo : demoList1){
            demoList2.add(demo.clone());
        }

        System.out.println("demoList1====================================");
        for(Demo demo : demoList1){
            System.out.println(demo);
        }
        System.out.println("demoList2====================================");
        for(Demo demo : demoList2){
            System.out.println(demo);
        }

        Demo demo3 = demoList2.get(0);
        demo3.setAge(9999);
        System.out.println("demoList1====================================");
        for(Demo demo : demoList1){
            System.out.println(demo);
        }
        System.out.println("demoList2====================================");
        for(Demo demo : demoList2){
            System.out.println(demo);
        }

        demoList2.remove(0);
        System.out.println("demoList1====================================");
        for(Demo demo : demoList1){
            System.out.println(demo);
        }
        System.out.println("demoList2====================================");
        for(Demo demo : demoList2){
            System.out.println(demo);
        }

        Demo demo4 = demoList2.get(0);
        demo4.setAge(6666);
        System.out.println("demoList1====================================");
        for(Demo demo : demoList1){
            System.out.println(demo);
        }
        System.out.println("demoList2====================================");
        for(Demo demo : demoList2){
            System.out.println(demo);      

結果

demoList1====================================
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo1, age=20, id=1234]
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo2, age=40, id=5678]
demoList2====================================
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo1, age=20, id=1234]
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo2, age=40, id=5678]
demoList1====================================
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo1, age=20, id=1234]
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo2, age=40, id=5678]
demoList2====================================
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo1, age=9999, id=1234]
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo2, age=40, id=5678]
demoList1====================================
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo1, age=20, id=1234]
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo2, age=40, id=5678]
demoList2====================================
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo2, age=40, id=5678]
demoList1====================================
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo1, age=20, id=1234]
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo2, age=40, id=5678]
demoList2====================================
Demo [birthDay=Tue Jan 09 21:00:03 CST 2018, userName=demo2, age=6666, id=5678]