最近在學java,今天學到了數組這部分,發現一個問題,比較有趣(或者麻煩),拿出來說說。

java.lang.System的靜態方法arraycopy()可以實現數組的復制,講課的老師說這個方法效率比較高,如果數組有成千上萬個元素,那么用這個方法,比用for語句循環快不少。于是我試了試,發現以下問題。

如果是復制一個一位數組,那么改變復制后的數組并不影響原數組。但是如果復制一個二維數組,那么改變其中任何一個數組,那么另一個的值也發生了變化。開始不是很明白,后來上網查了查資料,理解了其中奧妙。

java其實沒有二維數組的概念,平常實現的二維數組只是元素是一維數組的一維數組,而數組也是引用類型,繼承自Object類。數組是new出來的。這些性質也就導致arraycopy()二維數組時出現的問題。

如果是一維數組,那么元素都是基礎類型(如int,double等),使用arraycopy()方法后,是把原數組的值傳給了新數組,屬于值傳遞。而如果是二維數組,數組的第一維裝的是一個一維數組的引用,第二維里是元素數值。對二維數組應用arraycopy()方法后,第一維的引用被復制給新數組的第一維,也就是兩個數組的第一維都指向相同的“那些數組”。而這時改變其中任何一個數組的元素的值,其實都修改了“那些數組”的元素的值,所以原數組和新數組的元素值都一樣了。

OK,就是這樣。

不明白可以看看這個例子:


public class TestArrayCopy {

/**
@param args
*/
public static void main(String[] args) {
// TODO 自動生成方法存根

String[] s1 
= {"中國","山西","太原","TYUT","zyy","加拿大","不知道哪個州","不知道哪個市","不知道哪個學校","yxf"};
String[] s2 
= new String[10];
System.arraycopy(s1, 
0, s2, 010);
s2[
6= "假設蒙大拿州";
s2[
7= "假設蒙特利爾市";
s2[
8= "假設Montreal商學院";

System.out.println(
"This is s1");
for(int i = 0;i < s1.length ;i++){
System.out.print(s1[i] 
+ ",");
}

System.out.println(
"\nThis is s2");
for(int i = 0;i < s2.length ;i++){
System.out.print(s2[i] 
+ ",");
}

String[][] s3 
= {{"中國","山西","太原","TYUT","zyy"},{"加拿大","不知道哪個州","不知道哪個市","不知道哪個學校","yxf"}};
String[][] s4 
= new String[s3.length][s3[0].length];
System.arraycopy(s3, 
0, s4, 0, s3.length);

System.out.println(
"\nThis is original s3");
for(int i = 0;i < s3.length ;i++){
for(int j = 0; j< s3[0].length ;j++){
System.out.print(s3[i][j] 
+ ",");
}
}

s4[
1][1= "假設蒙大拿州";
s4[
1][2= "假設蒙特利爾市";
s4[
1][3= "假設Montreal商學院";

System.out.println(
"\nThis is s3 after s4 has changed.");
for(int i = 0;i < s3.length ;i++){
for(int j = 0; j< s3[0].length ;j++){
System.out.print(s3[i][j] 
+ ",");
}
}

System.out.println(
"\nThis is s4");
for(int i = 0;i < s4.length ;i++){
for(int j = 0; j < s4[0].length ; j++){
System.out.print(s4[i][j] 
+ ",");
}

}
}

}

結果:

This is s1
中國,山西,太原,TYUT,zyy,加拿大,不知道哪個州,不知道哪個市,不知道哪個學校,yxf,
This is s2
中國,山西,太原,TYUT,zyy,加拿大,假設蒙大拿州,假設蒙特利爾市,假設Montreal商學院,yxf,
This is original s3
中國,山西,太原,TYUT,zyy,加拿大,不知道哪個州,不知道哪個市,不知道哪個學校,yxf,
This is s3 after s4 has changed.
中國,山西,太原,TYUT,zyy,加拿大,假設蒙大拿州,假設蒙特利爾市,假設Montreal商學院,yxf,
This is s4
中國,山西,太原,TYUT,zyy,加拿大,假設蒙大拿州,假設蒙特利爾市,假設Montreal商學院,yxf,