最近在學(xué)java,今天學(xué)到了數(shù)組這部分,發(fā)現(xiàn)一個(gè)問(wèn)題,比較有趣(或者麻煩),拿出來(lái)說(shuō)說(shuō)。

java.lang.System的靜態(tài)方法arraycopy()可以實(shí)現(xiàn)數(shù)組的復(fù)制,講課的老師說(shuō)這個(gè)方法效率比較高,如果數(shù)組有成千上萬(wàn)個(gè)元素,那么用這個(gè)方法,比用for語(yǔ)句循環(huán)快不少。于是我試了試,發(fā)現(xiàn)以下問(wèn)題。

如果是復(fù)制一個(gè)一位數(shù)組,那么改變復(fù)制后的數(shù)組并不影響原數(shù)組。但是如果復(fù)制一個(gè)二維數(shù)組,那么改變其中任何一個(gè)數(shù)組,那么另一個(gè)的值也發(fā)生了變化。開(kāi)始不是很明白,后來(lái)上網(wǎng)查了查資料,理解了其中奧妙。

java其實(shí)沒(méi)有二維數(shù)組的概念,平常實(shí)現(xiàn)的二維數(shù)組只是元素是一維數(shù)組的一維數(shù)組,而數(shù)組也是引用類(lèi)型,繼承自O(shè)bject類(lèi)。數(shù)組是new出來(lái)的。這些性質(zhì)也就導(dǎo)致arraycopy()二維數(shù)組時(shí)出現(xiàn)的問(wèn)題。

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

OK,就是這樣。

不明白可以看看這個(gè)例子:


public class TestArrayCopy {

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

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

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 
= {{"中國(guó)","山西","太原","TYUT","zyy"},{"加拿大","不知道哪個(gè)州","不知道哪個(gè)市","不知道哪個(gè)學(xué)校","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= "假設(shè)蒙大拿州";
s4[
1][2= "假設(shè)蒙特利爾市";
s4[
1][3= "假設(shè)Montreal商學(xué)院";

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] 
+ ",");
}

}
}

}

結(jié)果:

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