java 复制一个数组_Java复制数组的方法

本文详细介绍了Java数组拷贝的四种方法:循环赋值、System.arraycopy()的浅拷贝、Arrays.copyOf()的浅拷贝以及Object.clone()的深拷贝。特别强调了System.arraycopy()和Arrays.copyOf()在浅拷贝与深拷贝的区别,以及clone()在数组和对象上的特殊行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java数组拷贝主要有四种方法,分别是循环赋值,System.arraycopy(),Arrays.copyOf()(或者Arrays.copyOfRange)和clone()方法。下面分别介绍一下这几种拷贝。

一、循环拷贝(速度相对比较慢)

循环拷贝其实没什么好说的啦,就是用一个for循环进行元素的逐个拷贝,进行深拷贝或者浅复制这个大家可以自己把握。

二、System.arraycopy(浅拷贝)

这个是系统提供的拷贝方式,也是我们推荐使用的拷贝方式,它是浅拷贝,也就是说对于非基本类型而言,它拷贝的是对象的引用,而不是去新建一个新的对象。通过它的代码我们可以看到,这个方法不是用java语言写的,而是底层用c或者c++实现的,因而速度会比较快。

1 public static native voidarraycopy2 (Object src, int srcPos,Object dest, int destPos,int length);

通过源代码我们可以看到,关键字native说明它不是用java语言写的,而是调用其他语言的代码。

1、先来看看基本数据类型的System.arraycopy() 方法拷贝:

1 importjava.util.Arrays;2 public classTestDemo {3 public static voidmain(String[] args) {4

5 int[] array1 = new int[]{1,2,8,7,6};6 int[] array2 = new int[array1.length];7 System.arraycopy(array1, 0, array2, 0, array1.length);8

9 System.out.println("array1 = " +Arrays.toString(array1));10 System.out.println("array2 = " +Arrays.toString(array2));11 System.out.println("=========================");12

13 array2[0] = 100;14 System.out.println("array1 = " +Arrays.toString(array1));15 System.out.println("array2 = " +Arrays.toString(array2));16

17 }18 }

这段程序的结果是:

array1 = [1, 2, 8, 7, 6]

array2= [1, 2, 8, 7, 6]=========================array1= [1, 2, 8, 7, 6]

array2= [100, 2, 8, 7, 6]

由结果可以看出,当对复制数组的某个元素进行改变时,并不影响被复制数组对应元素,即对于基本数据类型来说System.arraycopy() 方法是深拷贝。

2、同样的,看一下当对象不是基本数据类型,而是引用数据类型时的情况

看以下例子:

1 classTestArray{2 private int val = 10;3 public void setVal(intval){4 this.val =val;5 }6 public intgetVal(){7 return this.val;8 }9 }10

11 public classTestDemo {12 /**数组输出方法*/

13 public static voidprintArray(TestArray[] array){14 for(int i = 0;i < array.length;i++){15 System.out.print(array[i].getVal()+" ");16 }17 System.out.println();18 }19

20 public static voidmain(String[] args) {21 TestArray[] array1 = new TestArray[3];22 //数组引用赋值

23 for (int i = 0; i < array1.length; i++){24 array1[i] = newTestArray();25 }26

27 TestArray[] array2 = newTestArray[array1.length];28 //数组System.arraycopy()方法复制

29 System.arraycopy(array1,0,array2,0,array1.length);30

31 printArray(array1);32 printArray(array2);33 System.out.println("==========");34

35 array2[0].setVal(100);;36 printArray(array1);37 printArray(array2);38 }39 }

这段程序的结果是:

10 10 10

10 10 10

==========

100 10 10

100 10 10

由结果可以看出,当对复制数组的某个元素进行改变时,被复制数组对应元素也随之改变,即对于引用数据类型来说 System.arraycopy() 方法是浅拷贝。

三、Arrays.copyOf(浅拷贝)

这个方法也是浅拷贝,为什么呢?我们看一下它的源代码就知道了。

1 public static byte[] copyOfRange(byte[] original, int from, intto) {2 int newLength = to -from;3 if (newLength < 0)4 throw new IllegalArgumentException(from + " > " +to);5 byte[] copy = new byte[newLength];6 System.arraycopy(original, from, copy, 0,Math.min(original.length -from, newLength));7 returncopy;8 }

可以看到其实Arrays.copyOf()方法在底层是调用了 System.arraycopy() 方法来实现复制,即可以把Arrays.copyOf() 方法看作是 System.arraycopy() 方法的衍生方法,故它的执行机理与 System.arraycopy() 方法相同。  所以 Arrays.copyOf() 方法对于基本数据类型来说是深拷贝,对引用类型来说是浅拷贝。

四、对象拷贝(Object.clone)

clone()比较特殊,对于对象而言,它是深拷贝,但是对于数组而言,它是浅拷贝。  首先讲一下对象的拷贝,它是深拷贝,大家可以用对象去测试一下。下面我们看一下它的源代码:

1 protected native Object clone() throws CloneNotSupportedException;

这里也有native关键字,所以也是底层的c语言实现的。  还要注意的是,这里修饰符是protected,也就是说,我们创建了一个Object类以后,是不能直接调用这个clone()方法的,因为protected关键字只允许同一个包内的类和它的子类调用,所以我们声明一个object类时,肯定不是同一个包内,所以就不能去调用它。  要调用这个方法,就需要我们写一个类,然后声明实现cloneable接口就好了,不需要去显示地声明继承于object,因为java中的类如果不显示说明父类的话,默认父类就是object。然后我们继承这个方法:

1 @Override2 public Object clone() throwsCloneNotSupportedException {3 //TODO Auto-generated method stub

4 return super.clone();5 }

这里需要是,为了能够在不同包内去调用这个方法,我们需要把这个权限升级为public。现在我们就可以调用这个类的clone()方法去拷贝我们的类了。

五、数组拷贝

对于数组而言,它不是简单的将引用赋值为另外一个数组引用,而是创建一个新的数组。但是我们知道,对于数组本身而言,它它的元素是对象的时候,本来数组每个元素中保存的就是对象的引用,所以,拷贝过来的数组自然而言也是对象的引用,所以对于数组对象元素而言,它又是浅拷贝。我们用以下代码验证一下:

1 class Aby implementsCloneable{2 public inti;3 public Aby(inti) {4 this.i =i;5 }6 @Override7 public Object clone() throwsCloneNotSupportedException {8 //TODO Auto-generated method stub

9 return super.clone();10 }11 }12 public classSolution {13

14 public static void main(String[] args) throwsCloneNotSupportedException {15 Aby aby1 = new Aby(1);16 Aby aby2 =(Aby) aby1.clone();17 aby1.i = 2;18 System.out.println(aby1.i); //2

19 System.out.println(aby2.i); //1

20

21 Aby[] arr ={aby1,aby2};22

23 Aby[] arr2 =arr.clone();24 arr2[0].i = 3;25 System.out.println(arr[0].i); //3

26 System.out.println(arr2[0].i); //3

27 }28 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值