配列コピーの検証
配列のコピー を調べててよくわからなかったので
あれこれ実験してみた。
【環境】
J2SE6
Android 1.6
int[] intArrayFrom = {1, 2, 3, 4, 5};
int[] intArrayTo = intArrayFrom;
Log.i(“From”, Arrays.toString(intArrayFrom) );
// [1, 2, 3, 4, 5]
Log.i(“To”, Arrays.toString(intArrayTo) );
// [1, 2, 3, 4, 5]
intArrayFrom[2] = 88;
Log.i(“From”, Arrays.toString(intArrayFrom) );
// [1, 2, 88, 4, 5]
Log.i(“To”, Arrays.toString(intArrayTo) );
// [1, 2, 88, 4, 5]
intArrayTo[0] = 123;
Log.i(“From”, Arrays.toString(intArrayFrom) );
// [123, 2, 88, 4, 5]
Log.i(“To”, Arrays.toString(intArrayTo) );
// [123, 2, 88, 4, 5]
// 2次元配列
int[][] intMultidimensionalArrayFrom = { {1, 2, 3, 4, 5}, {6, 7, 8} };
int[][] intMultidimensionalArrayTo = intMultidimensionalArrayFrom;
Log.i(“From”, Arrays.deepToString(intMultidimensionalArrayFrom) );
// [[1, 2, 3, 4, 5], [6, 7, 8]]
Log.i(“To”, Arrays.deepToString(intMultidimensionalArrayTo) );
// [[1, 2, 3, 4, 5], [6, 7, 8]]
intMultidimensionalArrayFrom[0][2] = 88;
Log.i(“From”, Arrays.deepToString(intMultidimensionalArrayFrom) );
// [[1, 2, 88, 4, 5], [6, 7, 8]]
Log.i(“To”, Arrays.deepToString(intMultidimensionalArrayTo) );
// [[1, 2, 88, 4, 5], [6, 7, 8]]
intMultidimensionalArrayTo[1][0] = 123;
Log.i(“From”, Arrays.deepToString(intMultidimensionalArrayFrom) );
// [[1, 2, 88, 4, 5], [123, 7, 8]]
Log.i(“To”, Arrays.deepToString(intMultidimensionalArrayTo) );
// [[1, 2, 88, 4, 5], [123, 7, 8]][/android]
うん、間違いなくシャローコピー(参照渡し)だね。 😎
int[] intArrayFrom = {1, 2, 3, 4, 5};
int[] intArrayTo = new int[intArrayFrom.length];
for (int i = 0; i < intArrayFrom.length; i++) { intArrayTo[i] = intArrayFrom[i]; } Log.i("From", Arrays.toString(intArrayFrom) ); // [1, 2, 3, 4, 5] Log.i("To", Arrays.toString(intArrayTo) ); // [1, 2, 3, 4, 5] intArrayFrom[2] = 88; Log.i("From", Arrays.toString(intArrayFrom) ); // [1, 2, 88, 4, 5] Log.i("To", Arrays.toString(intArrayTo) ); // [1, 2, 3, 4, 5] intArrayTo[0] = 123; Log.i("From", Arrays.toString(intArrayFrom) ); // [1, 2, 88, 4, 5] Log.i("To", Arrays.toString(intArrayTo) ); // [123, 2, 3, 4, 5] // 2次元配列 int[][] intMultidimensionalArrayFrom = { {1, 2, 3, 4, 5}, {6, 7, 8} }; int[][] intMultidimensionalArrayTo = new int[intMultidimensionalArrayFrom.length][]; for (int i = 0; i < intMultidimensionalArrayFrom.length; i++) { for (int j = 0; j < intMultidimensionalArrayFrom[i].length; j++) { intMultidimensionalArrayTo[i] = new int[intMultidimensionalArrayFrom[i].length]; intMultidimensionalArrayTo[i][j] = intMultidimensionalArrayFrom[i][j]; } } Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) ); // [[1, 2, 3, 4, 5], [6, 7, 8]] Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) ); // [[1, 2, 3, 4, 5], [6, 7, 8]] intMultidimensionalArrayFrom[0][2] = 88; Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) ); // [[1, 2, 88, 4, 5], [6, 7, 8]] Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) ); // [[1, 2, 3, 4, 5], [6, 7, 8]] intMultidimensionalArrayTo[1][0] = 123; Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) ); // [[1, 2, 88, 4, 5], [6, 7, 8]] Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) ); // [[1, 2, 3, 4, 5], [123, 7, 8]][/android] うんうん、間違いなくディープコピー(値渡し)だね。 😎
int[] intArrayFrom = {1, 2, 3, 4, 5};
int[] intArrayTo = (int[]) intArrayFrom.clone();
Log.i(“From”, Arrays.toString(intArrayFrom) );
// [1, 2, 3, 4, 5]
Log.i(“To”, Arrays.toString(intArrayTo) );
// [1, 2, 3, 4, 5]
intArrayFrom[2] = 88;
Log.i(“From”, Arrays.toString(intArrayFrom) );
// [1, 2, 88, 4, 5]
Log.i(“To”, Arrays.toString(intArrayTo) );
// [1, 2, 3, 4, 5]
intArrayTo[0] = 123;
Log.i(“From”, Arrays.toString(intArrayFrom) );
// [1, 2, 88, 4, 5]
Log.i(“To”, Arrays.toString(intArrayTo) );
// [123, 2, 3, 4, 5]
// 2次元配列
int[][] intMultidimensionalArrayFrom = { {1, 2, 3, 4, 5}, {6, 7, 8} };
int[][] intMultidimensionalArrayTo = (int[][]) intMultidimensionalArrayFrom.clone();
Log.i(“From”, Arrays.deepToString(intMultidimensionalArrayFrom) );
// [[1, 2, 3, 4, 5], [6, 7, 8]]
Log.i(“To”, Arrays.deepToString(intMultidimensionalArrayTo) );
// [[1, 2, 3, 4, 5], [6, 7, 8]]
intMultidimensionalArrayFrom[0][2] = 88;
Log.i(“From”, Arrays.deepToString(intMultidimensionalArrayFrom) );
// [[1, 2, 88, 4, 5], [6, 7, 8]]
Log.i(“To”, Arrays.deepToString(intMultidimensionalArrayTo) );
// [[1, 2, 88, 4, 5], [6, 7, 8]]
intMultidimensionalArrayTo[1][0] = 123;
Log.i(“From”, Arrays.deepToString(intMultidimensionalArrayFrom) );
// [[1, 2, 88, 4, 5], [123, 7, 8]]
Log.i(“To”, Arrays.deepToString(intMultidimensionalArrayTo) );
// [[1, 2, 88, 4, 5], [123, 7, 8]][/android]
うっは、本当だったんだ・・・。
そもそも、こんな検証をしようとしたのは、参考元サイトに
「1次元配列と多次元配列で異なる」
と書いてあったのがきっかけ。
そんなアホな! と思った私は検証する気になった。
でも事実はこの通り・・・。
Object.clone() メソッドでは
1次元配列 ・・・ ディープコピー(値渡し)
多次元配列 ・・・ シャローコピー(参照渡し)
int[] intArrayFrom = {1, 2, 3, 4, 5};
int[] intArrayTo = new int[intArrayFrom.length];
System.arraycopy(intArrayFrom, 0, intArrayTo, 0, intArrayFrom.length);
Log.i(“From”, Arrays.toString(intArrayFrom) );
// [1, 2, 3, 4, 5]
Log.i(“To”, Arrays.toString(intArrayTo) );
// [1, 2, 3, 4, 5]
intArrayFrom[2] = 88;
Log.i(“From”, Arrays.toString(intArrayFrom) );
// [1, 2, 88, 4, 5]
Log.i(“To”, Arrays.toString(intArrayTo) );
// [1, 2, 3, 4, 5]
intArrayTo[0] = 123;
Log.i(“From”, Arrays.toString(intArrayFrom) );
// [1, 2, 88, 4, 5]
Log.i(“To”, Arrays.toString(intArrayTo) );
// [123, 2, 3, 4, 5]
// 2次元配列
int[][] intMultidimensionalArrayFrom = { {1, 2, 3, 4, 5}, {6, 7, 8} };
int[][] intMultidimensionalArrayTo = new int[intMultidimensionalArrayFrom.length][];
for (int i = 0; i < intMultidimensionalArrayFrom.length; i++) { intMultidimensionalArrayTo[i] = new int[intMultidimensionalArrayFrom[i].length]; System.arraycopy(intMultidimensionalArrayFrom[i], 0, intMultidimensionalArrayTo[i], 0, intMultidimensionalArrayFrom[i].length); } Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) ); // [[1, 2, 3, 4, 5], [6, 7, 8]] Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) ); // [[1, 2, 3, 4, 5], [6, 7, 8]] intMultidimensionalArrayFrom[0][2] = 88; Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) ); // [[1, 2, 88, 4, 5], [6, 7, 8]] Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) ); // [[1, 2, 3, 4, 5], [6, 7, 8]] intMultidimensionalArrayTo[1][0] = 123; Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) ); // [[1, 2, 88, 4, 5], [6, 7, 8]] Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) ); // [[1, 2, 3, 4, 5], [123, 7, 8]][/android] ん? あれ? これってディープコピー(値渡し)では? リファレンス を見ても特に記述はない気がするが 私が愛して止まない Java の道 を初め、あちこちのサイトに 「arraycopy メソッドはシャローコピーである」 と書いてある。 私がスクリプトの書き方を間違えたのかしら・・・。 それとも仕様が変わった? Android だから? 🙄
Android は J2SE5 相当のため実証できず。