category: Java
DATE : 2006/05/16 (Tue)
DATE : 2006/05/16 (Tue)
Java には、System#arraycopy(Object, int, Object, int, int) という、配列の中身を高速にコピーするメソッドが用意されています。
このメソッドは Java ではなく機械語で実装されています。そのため、 for ループなどのコピーよりも素早くコピーできます。
具体的には、次のように配列の中身をコピーします。
// コピー元
int[] src = {1, 2, 3};
// コピー先
int[] dest = new int[src.length];
// コピー
System.arraycopy(src, 0, dest, 0, src.length);
ただし、コピーを行う配列がいわゆる2次元以上の配列の場合は注意が必要です。
Java では、2次元配列は「配列の配列」として表現します。つまり、配列オブジェクトを格納する配列の中に配列オブジェクトが入っているという考えです。
int[][] array;
// 異なる書き方で同じ容量の配列を確保
array = new int[2][2];
array = {new int[2], new int[2]};
配列オブジェクトは参照型です。System#arraycopy メソッドの場合、参照値はそのままコピーされます。つまり、コピー元とコピー先で入れ子になっている同じ配列オブジェクトを指すわけです。
int[][] src = {{1, 2}, {3, 4}};
int[][] dest = {{5, 6}, {7, 8}};
System.arraycopy(src, 0, dest, 0, 2);
System.out.println(src[0] == dest[0]);
上記の出力は true となります。もしも入れ子になった配列オブジェクトの中身がコピーされていれば、src[0] と dest[0] は同一のインスタンスではないため、 false となるはずです。参照がコピーされたために、src[0] と dest[0] は同一のインスタンスを指すようになり、 true となったわけです。
これではコピーできたとは言えません。src[0][0] の値を書き換えると、dest[0][0] の中身も変わってしまいます。
そこで、入れ子になっている配列の中身をコピーする場合は、その配列を直接 System#arraycopy メソッドに渡すようにします。
int[][] src = {{1, 2}, {3, 4}};
int[][] dest = {{5, 6}, {7, 8}};
for (int i = 0; i < src.length; i++) {
System.arraycopy(src[i], 0, dest[i], 0, 2);
}
System.out.println(src[0] == dest[0]);
この場合、出力は false となります。
参考文献
PR
●この記事にコメントする
忍者ブログ [PR]