今天在读别人代码的时候,发现了一个数组之间复制很不错的方法,就分享记录下吧。同时小小的研究下了它的使用方法。
System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制。其函数原型是:
public static void arraycopy(Object src,
int srcPos,
Object dest,
int destPos,
int length)
src:源数组;
srcPos:复制源数组的起始位置;
dest:目的数组;
destPos:放置目的数组的起始位置;
length:需要复制的长度。
注意:src 和 dest都必须是同类型或者可以进行转换类型的数组。
1.一维数组的复制
函数也很好理解,直接上代码吧。
import java.util.Arrays;
public class MyClass {
public static void main(String[] args) {
int [] srcArray = new int []{0,1,2,3,4,5,6,7,8} ;
int [] destArray = new int [srcArray.length] ;
System.arraycopy(srcArray, 0, destArray, 0, srcArray.length) ;
System.out.println(Arrays.toString(srcArray));
System.out.println(Arrays.toString(destArray));
}
}
arraycopy()实现复制
不仅如此,更加有趣的是这个函数可以实现自己到自己的复制,比如:
import java.util.Arrays;
public class MyClass {
public static void main(String[] args) {
int [] srcArray = new int []{0,1,2,3,4,5,6,7,8} ;
System.out.println(Arrays.toString(srcArray));
System.arraycopy(srcArray, 0, srcArray , 3, 3) ;
System.out.println(Arrays.toString(srcArray));
}
}
则结果为:
arraycopy()自我复制
实现过程是这样的,先生成一个长度为length的临时数组,将fun数组中srcPos到srcPos+length-1之间的数据拷贝到临时数组中,再执行System.arraycopy(临时数组,0,srcArray ,3,3)。
2.一维数组的交换
其实从arraycopy()自我复制的例子就可以想到,只要借助于临时数组,就可以实现数组左边和右边的交换。
import java.util.Arrays;
public class MyClass {
public static void main(String[] args) {
int [] srcArray = new int []{0,1,2,3,4,5,6,7,8} ;
int [] destArray = new int[srcArray.length];
//从第3位开始数组左右交换
int index = 3;
System.arraycopy(srcArray, index, destArray, 0, srcArray.length-index);
System.arraycopy(srcArray, 0, destArray, srcArray.length-index, index);
System.out.println(Arrays.toString(srcArray));
System.out.println(Arrays.toString(destArray));
}
}
arraycopy()实现交换
怎么样,是不是看起来代码很简洁,不需要调用for或者while循环去实现数组的交换啦。
3.二维数组的复制
由于java没有二维数组的概念,平常实现的二维数组只是元素是一维数组的一维数组,而数组也是引用类型,继承自Object类。数组是new出来的。这些性质也就导致arraycopy()二维数组会出现问题。这是个坑,不可大意。怎么样一个坑呢,我们来对比下一维数组复制和二维数组复制的代码你就知道啦。
import java.util.Arrays;
public class MyClass {
public static void main(String[] args) {
int [] srcArray = new int []{0,1,2,3,4,5,6,7,8} ;
int [] destArray = new int [srcArray.length] ;
System.arraycopy(srcArray, 0, destArray, 0, srcArray.length) ;
System.out.println("srcArray:"+Arrays.toString(srcArray));
System.out.println("destArray:"+Arrays.toString(destArray));
destArray[0] = 9 ; destArray[1] = 9 ;
System.out.println("srcArray after changed value:"+Arrays.toString(srcArray));
System.out.println("destArray after changed value:"+Arrays.toString(destArray));
}
}
一维数组复制
从结果中可以看出,设置destArray[0] = 9 ,destArray[1] = 9 后,srcArray after changed value的结果并没有改变,仅仅只有destArray after changed value的结果改变。所以有如下结论:
**
在一维数组中,元素都是基础类型(如int,double等),使用arraycopy()方法后,是把原数组的值传给了新数组,属于值传递。
**
接下来我们看看二维数组的复制代码:
import java.util.Arrays;
public class MyClass {
public static void main(String[] args) {
char [][]one = new char[][]{{'a','b'},{'c','d'},{'e','f'}};
System.out.println("srcArray:"+Arrays.toString(one[0]));
char [][] another = new char [2][2] ;
System.arraycopy(one, 0, another, 0, 2) ;
System.out.println("destArray:"+Arrays.toString(another[0]));
one[0][0] = 'x' ; one[0][1] = 'y' ;
System.out.println("srcArray after changed value:"+Arrays.toString(one[0]));
System.out.println("destArray after changed value:"+Arrays.toString(another[0]));
}
}
二维数组复制
从结果中可以看出,设置one[0][0] = 'x',one[0][1] = 'y' 后,srcArray after changed value的结果和destArray after changed value的结果相同。所以有如下结论:
**
二维数组使用arraycopy()方法后,第一维的引用被复制给新数组的第一维,也就是两个数组的第一维都指向相同的“那些数组”。而这时改变其中任何一个数组的元素的值,其实都修改了“那些数组”的元素的值,所以原数组和新数组的元素值都一样了。
**
总结:
1.一维数组的复制属于值传递 ,修改副本原来的不会变
2.二维的数组,复制的结果是将源二维数组里一维数组的引用变量传递给副本,修改任意一个数组的值,另一个数组的值也会相应改变。也就是one[2][2]中,one[i]是复制,one[i][j]是引用。