Java中数组的深拷贝和浅拷贝

一、数组浅拷贝的4种方式

1. 使用 copyOf() 方法对数组进行复制

jdk1.8的API文档中关于Arrays的copyOf方法:

    • static boolean[]copyOf(boolean[] original, int newLength)

      使用 false (如有必要)复制指定的数组,截断或填充,以使副本具有指定的长度。

      static byte[]copyOf(byte[] original, int newLength)

      复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。

      static char[]copyOf(char[] original, int newLength)

      复制指定的数组,截断或填充空字符(如有必要),以便复制具有指定的长度。

      static double[]copyOf(double[] original, int newLength)

      复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。

      static float[]copyOf(float[] original, int newLength)

      复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。

      static int[]copyOf(int[] original, int newLength)

      复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。

      static long[]copyOf(long[] original, int newLength)

      复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。

      static short[]copyOf(short[] original, int newLength)

      复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。

      static <T> T[]copyOf(T[] original, int newLength)

      复制指定的数组,用空值截断或填充(如有必要),以便复制具有指定的长度。

      static <T,U> T[]copyOf(U[] original, int newLength, <? extends T[]> newType)

      复制指定的数组,用空值截断或填充(如有必要),以便复制具有指定的长度。

2. 使用 CopyOfRange() 方法对数组进行复制

jdk1.8的API文档中关于Arrays的CopyOfRange方法:

    • static boolean[]copyOfRange(boolean[] original, int from, int to)

      将指定数组的指定范围复制到新数组中。

      static byte[]copyOfRange(byte[] original, int from, int to)

      将指定数组的指定范围复制到新数组中。

      static char[]copyOfRange(char[] original, int from, int to)

      将指定数组的指定范围复制到新数组中。

      static double[]copyOfRange(double[] original, int from, int to)

      将指定数组的指定范围复制到新数组中。

      static float[]copyOfRange(float[] original, int from, int to)

      将指定数组的指定范围复制到新数组中。

      static int[]copyOfRange(int[] original, int from, int to)

      将指定数组的指定范围复制到新数组中。

      static long[]copyOfRange(long[] original, int from, int to)

      将指定数组的指定范围复制到新数组中。

      static short[]copyOfRange(short[] original, int from, int to)

      将指定数组的指定范围复制到新数组中。

      static <T> T[]copyOfRange(T[] original, int from, int to)

      将指定数组的指定范围复制到新数组中。

      static <T,U> T[]copyOfRange(U[] original, int from, int to, <? extends T[]> newType)

      将指定数组的指定范围复制到新数组中。

3.使用 arraycopy() 方法

jdk1.8的API文档中关于System的arraycopy方法:

    • static voidarraycopy(Object src, int srcPos, Object dest, int destPos, int length)

      将指定源数组中的数组从指定位置复制到目标数组的指定位置。

      • 参数

        src - 源数组。

        srcPos - 源数组中的起始位置。

        dest - 目标数组。

        destPos - 目的地数据中的起始位置。

        length - 要复制的数组元素的数量。

4.使用 clone() 方法

clone() 方法也可以实现复制数组。该方法是类 Object 中的方法,可以创建一个有单独内存空间的对象。因为数组也是一个 Object 类,因此也可以使用数组对象的 clone() 方法来复制数组。

clone() 方法的返回值是 Object 类型,要使用强制类型转换为适当的类型。

对于基本数据类型的数组:
一维数组:深克隆;(重新分配空间,并将元素复制过去)
二维数组:浅克隆。(只传递引用)

二、数组深复制的方式

如何实现二维数组的深克隆呢?

对每一维数组调用clone方法。

int[][] a={{3,1,4,2,5},{4,2}};
int[][] b=new int[a.length][];
for(int i=0;i<a.length;i++){
        b[i]=a[i].clone();
}
b[0][0]=10;
System.out.println(b[0][0]+"  "+a[0][0]);
System.out.println(b[0]==a[0]);

一维对象数组的克隆

//浅克隆
class MyClass {
    int a;
    MyClass(int a){
        this.a = a;
    }

    @Override
    public String toString() {
        return ""+a;
    }

    void changeValue(int x){
        a = x;
    }
}
public class Blah
{
    public static void main(String[] args) {
        MyClass[] a={new MyClass(1),new MyClass(2), new MyClass(3),new MyClass(4),new MyClass(5)};
        MyClass[] b=a.clone();
        b[0].changeValue(10);
        System.out.println(b[0]+"  "+a[0]);//输出10  10
    }
}

//深克隆
class MyClass implements Cloneable{
    private int a;
    MyClass(int a){
        this.a = a;
    }

    @Override
    public String toString() {
        return ""+a;
    }

    void changeValue(int x){
        a = x;
    }

    @Override
    public MyClass clone(){
        MyClass myClass = null;
        try {
            myClass = (MyClass) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        /*如果类中存在非基本类型的属性,需要在这里对属性进行克隆(通过调用属性的clone()方法。*/
        return myClass;
    }
}
public class Blah {
    public static void main(String[] args) {
        MyClass[] a={new MyClass(1),new MyClass(2), new MyClass(3),new MyClass(4),new MyClass(5)};
        MyClass[] b = new MyClass[a.length];
        for(int i = 0; i < a.length; i++){
            b[i] = a[i].clone();
        }
        b[0].changeValue(10);
        System.out.println(b[0]+"  "+a[0]);//输出10 1
    }
}

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值