最近在學java,今天學到了數組這部分,發現一個問題,比較有趣(或者麻煩),拿出來說說。
java.lang.System的靜態方法arraycopy()可以實現數組的復制,講課的老師說這個方法效率比較高,如果數組有成千上萬個元素,那么用這個方法,比用for語句循環快不少。于是我試了試,發現以下問題。
如果是復制一個一位數組,那么改變復制后的數組并不影響原數組。但是如果復制一個二維數組,那么改變其中任何一個數組,那么另一個的值也發生了變化。開始不是很明白,后來上網查了查資料,理解了其中奧妙。
java其實沒有二維數組的概念,平常實現的二維數組只是元素是一維數組的一維數組,而數組也是引用類型,繼承自Object類。數組是new出來的。這些性質也就導致arraycopy()二維數組時出現的問題。
如果是一維數組,那么元素都是基礎類型(如int,double等),使用arraycopy()方法后,是把原數組的值傳給了新數組,屬于值傳遞。而如果是二維數組,數組的第一維裝的是一個一維數組的引用,第二維里是元素數值。對二維數組應用arraycopy()方法后,第一維的引用被復制給新數組的第一維,也就是兩個數組的第一維都指向相同的“那些數組”。而這時改變其中任何一個數組的元素的值,其實都修改了“那些數組”的元素的值,所以原數組和新數組的元素值都一樣了。
OK,就是這樣。
不明白可以看看這個例子:
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自動生成方法存根
String[] s1 = {"中國","山西","太原","TYUT","zyy","加拿大","不知道哪個州","不知道哪個市","不知道哪個學校","yxf"};
String[] s2 = new String[10];
System.arraycopy(s1, 0, s2, 0, 10);
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,