黑马程序员——Java基础---深层拷贝(数组、ArrayList)

来源:互联网 发布:易娱网络太古汇39楼 编辑:程序博客网 时间:2024/06/11 17:50

——- android培训、java培训、期待与您交流! ———-

JAVA中复制数组元素值:(深拷贝)

在JAVA里面,可以用复制语句“A=B”给基本类型的数据传递值,但是如果A,B是两个同类型的数组,复制就相当于将一个数组变量的引用传递给另一个数组;如果一个数组发生改变,那么引用同一数组的变量也要发生改变。

    public static void main(String[] args) {        int[] a={3,1,4,2,5};        int[] b=a;        b[0]=10;        System.out.println(b+"  "+a);        System.out.println(b==a);        System.out.println(b[0]+"  "+a[0]);    }    //结果: [I@15db9742  [I@15db9742    //      true    //      10  10 

为此就需要新建一个数组,而不单单是复制引用

1、使用FOR循环,将数组的每个元素复制
(当底层不是基本数据类型时:需要将每个对象调用clone方法,才能实现真正的复制)

    public static void main(String[] args) {        int[] a={3,1,4,2,5};        int[] b=new int[a.length];        for(int x=0;x<a.length;x++){            b[x]=a[x];        }        b[0]=10;        System.out.println(b[0]+"  "+a[0]);//输出 : 10  3        int[][] a2={{3,1,4,2,5},{4,2}};        int[][] b2=new int[a2.length][a2[0].length];        for(int x=0;x<a2.length;x++){            b2[x]=a2[x];        }        b2[0][0]=10;        System.out.println(b2[0][0]+"  "+a2[0][0]);    }// 输出: 10  10/*        int[][] a2={{3,1,4,2,5},{4,2}};        int[][] b2=new int[a2.length][a2[0].length];        for(int x=0;x<a2.length;x++){            b2[x]=a2[x].clone();        }        b2[0][0]=10;        System.out.println(b2[0][0]+"  "+a2[0][0]);//      输出:10   3*/

2、使用clone方法,得到数组的值,而不是引用

/*        int[] a={3,1,4,2,5};        int[] b=a.clone();        b[0]=10;        System.out.println(b[0]+"  "+a[0]);//      输出:10   3*/

3、使用System.arraycopy(s,start1,t,start2,length)方法

    public static void main(String[] args) {        int[] a={3,1,4,2,5};        int[] b=new int[a.length];        System.arraycopy(a, 0, b, 0, a.length);        b[0]=10;        System.out.println(b[0]+"  "+a[0]);//      输出:10   3           }/*注:s是原数组,t是目标数组,start1&start2是开始复制下标,length一般是s的长度,由于arraycopy方法不给目标数组分配内存空间,所以必需要先为t分配内存空间!*/

注意:

1.上面方法中arraycopy效率较高。2. 以上方法,只限一维数组,多维数组,要具体到一维复制才能实现复制数组元素的值。3. clone 和 arraycopy对二维数组进行复制时,是浅拷贝

JAVA中复制集合元素值:(深拷贝)

// 为了验证方便,这里不再覆盖 toString() 方法public class FuZhi {    public static void main(String[] args) {        Student c = new Student("zhan",22);        Student d = new Student("zhan",22);        Student e = new Student("zhan",22);        Student f = new Student("zhan",22);        List<Student> li = new ArrayList<Student>();        li.add(c);        li.add(e);        li.add(d);        li.add(f);        List<Student> li2 = new ArrayList<Student>();        li2=li;        li.set(0, new Student("wang",23));// 结果1 System.out.println(li2.toString());        System.out.println("li[0]:\t"+li.get(0)                            +"\r\nli2[0]\t"+li2.get(0)            +"\r\n是否相等:"+(li2.get(0)==li.get(0)));    }}class Student{    private String name;    private int age;    Student(String name, int age){        this.name=name;        this.age =age;    }//  public String toString(){   //结果1//      return name+" "+age;//  }}/*输出结果1、:[wang 23, zhan 22, zhan 22, zhan 22]输出结果2、:li[0]:  Hello.Student@15db9742 li2[0]: Hello.Student@15db9742是否相等:true*/

ArryList()深层拷贝方法.

1、 最简洁的 new ArrayList( src)

public class FuZhi {    public static void main(String[] args) {        Student c = new Student("zhan",22);        Student d = new Student("zhan",22);        Student e = new Student("zhan",22);        Student f = new Student("zhan",22);        List<Student> li = new ArrayList<Student>();        li.add(c);        li.add(e);        li.add(d);        li.add(f);        List<Student> li2 = new ArrayList<Student>();        //  建立一个集合副本 ,复制内部所有元素        li2 =new ArrayList<Student>(li);        li.set(0, new Student("wang",23));        System.out.println("li[0]:\t"+li.get(0)+"\r\nli2[0]\t"                            +li2.get(0)+"\r\n是否相等:"                            +(li2.get(0)==li.get(0)));    }}class Student {    private String name;    private int age;    Student(String name, int age){        this.name=name;        this.age =age;    }    public String toString(){        return name+" "+age;    }}/*li[0]:  wang 23li2[0]  zhan 22是否相等:false*/

2、 覆盖 clone(不建议)
通过覆盖 Object 中的 clone(),进行复制
不过只限一维,多维需要多层覆盖,很麻烦

import java.util.ArrayList;// 首先类 必须实现 Cloneable 接口public class TestClone implements Cloneable {    private ArrayList<String> arrayList = new ArrayList<String>();  // 第二 最高权限覆写 clone() 方法    public TestClone clone() {        TestClone testClone = null;        try {            testClone = (TestClone) super.clone();            testClone.arrayList =             (ArrayList<String>) this.arrayList.clone();        } catch (CloneNotSupportedException e) {            e.printStackTrace();        }        return testClone;    }    public ArrayList<String> getArrayList() {        return this.arrayList;    }    public void setValue(String value) {        arrayList.add(value);    }    public static void main(String[] args) {        TestClone testClone = new TestClone();        testClone.setValue("张三");         //调用 clone 方法        TestClone testClone1 = testClone.clone();        testClone1.setValue("李四");        System.out.println(testClone.getArrayList());        System.out.println(testClone1.getArrayList());    }}/*运行结果:        [张三]        [张三, 李四]*/

3、通过序列化

就是把ArrayList的原来的对象进行序列化,然后通过反序列化读取出来,就可以了。
当然,记着放到集合中的元素也要能够序列化,所以必须实现Serializable接口。

package test;   import java.io.Serializable;   // 实现序列化需要实现接口 Serializable public class Userinfo implements Serializable    {       private int id;       private String name;       public int getId() {           return id;       }       public void setId(int id) {           this.id = id;       }       public String getName() {           return name;       }       public void setName(String name) {           this.name = name;       }   }  // 下面是测试:import java.io.ByteArrayInputStream;   import java.io.ByteArrayOutputStream;   import java.io.IOException;   import java.io.ObjectInputStream;   import java.io.ObjectOutputStream;   import java.util.ArrayList;   import java.util.List;   public class TestMain {       /**       * @param args       */      public static void main(String[] args) {             List src = new ArrayList(2);           Userinfo ui1 = new Userinfo();           ui1.setId(1);           ui1.setName("aaa");           src.add(ui1);           Userinfo ui2 = new Userinfo();           ui1.setId(2);           ui1.setName("bbb");           src.add(ui2);           List dest = new ArrayList(2);           TestMain test = new TestMain();           try {               dest = test.deepCopy(src);           } catch (IOException e) {                e.printStackTrace();           } catch (ClassNotFoundException e) {               e.printStackTrace();           }           System.out.println(src==dest);           Userinfo u = (Userinfo)src.get(0);           Userinfo uu = (Userinfo)dest.get(0);           uu.setName("dkkdkddk");           System.out.println(u.getName());           System.out.println(uu.getName());       }     // 复制代码    public List deepCopy(List src) throws IOException, ClassNotFoundException{           ByteArrayOutputStream byteOut = new ByteArrayOutputStream();           ObjectOutputStream out = new ObjectOutputStream(byteOut);           out.writeObject(src);           ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());           ObjectInputStream in =new ObjectInputStream(byteIn);           List dest = (List)in.readObject();           return dest;       }   }/*输出结果:        false        bbb        ccc*/

——- android培训、java培训、期待与您交流! ———-

0 0
原创粉丝点击