歡迎糾錯运杭,轉(zhuǎn)載注明出處院塞,have a nice day!
今天在做項目的時候有個需求要用到二維數(shù)組復(fù)制,我不假思索地以為和一維數(shù)組一樣戏溺,結(jié)果出錯了渣蜗,特此記錄一下。
Arrays.copyOf()方法返回的拷貝數(shù)組的地址是否指向原數(shù)組旷祸?
答案很明顯是否的耕拷,因為在源碼中很明顯是new了個新數(shù)組返回。
public static int[] copyOf(int[] original, int newLength) {
//new一個新數(shù)組托享,然后調(diào)用System.arraycopy復(fù)制
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
雖然返回的數(shù)組地址與原數(shù)組不同骚烧,但是數(shù)組中的數(shù)據(jù)就未必了,上代碼:
新建兩個數(shù)組闰围,分別存放基本數(shù)據(jù)和對象赃绊,然后對他們進(jìn)行拷貝,再對拷貝的數(shù)組的第一個元素進(jìn)行修改羡榴”滩椋可以看出,啊a1數(shù)組的元素并未發(fā)生改變校仑,而a2數(shù)組的元素改變了忠售。
public class TestArraysCopy {
public static void main(String[] args) {
int[] a1 = new int[] {1, 2, 3, 4};
Num[] a2 = new Num[] {new Num(1), new Num(2), new Num(3), new Num(4)};
int[] c1 = Arrays.copyOf(a1, a1.length);
Num[] c2 = Arrays.copyOf(a2, a2.length);
c1[0] = 0;
c2[0].num = 0;
System.out.println("a1: " + a1[0] + " c1: " + c1[0]);//a1: 1 c1: 0
System.out.println("a2: " + a2[0].num + " c2: " + c2[0].num);//a2: 0 c2: 0
}
}
class Num{
int num;
public Num(int num) {
this.num = num;
}
}
可以看出,對于對象數(shù)組的copy迄沫,數(shù)組中的元素引用的是原數(shù)組中對象的地址稻扬。我們debug來看一下數(shù)組地址
發(fā)現(xiàn),a1,a2與c1,c2的數(shù)組地址不同,但a2與c2的元素的地址是相同的邢滑,所以證實上面的說法腐螟。
那么二維數(shù)組的拷貝有什么不同嗎?
我之前對二維數(shù)組的拷貝操作是這樣的
int[][] a3 = new int[][] {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int[][] c3 = Arrays.copyOf(a3, a3.length);
c3[0][0] = 0;
System.out.println("a3: " + a3[0][0] + " c3: " + c3[0][0]);//a3: 0 c3: 0
我們都知道困后,數(shù)組在java中是看做對象來處理的乐纸,如果按照我之前的操作,則會把a(bǔ)3中的每個子數(shù)組的地址傳遞到c3中摇予。所以對二維數(shù)組的拷貝要這么做:
int[][] a3 = new int[][] {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int[][] c3 = new int[a3.length][];
for (int i = 0; i < a3.length; i++) {
c3[i] = Arrays.copyOf(a3[i], a3[i].length);
}
c3[0][0] = 0;
System.out.println("a3: " + a3[0][0] + " c3: " + c3[0][0]);//a3: 1 c3: 0
先為c3開辟3個新地址汽绢,然后就和一維數(shù)組拷貝一樣了。
注意:當(dāng)二維數(shù)組是對象數(shù)組的時候侧戴,想要拷貝就只能老老實實用for循環(huán)宁昭,new一個新對象,將舊對象的數(shù)據(jù)傳遞給新對象酗宋。