配列コピーの検証

Posted by muchag | Java |
初回投稿:2011-04-20 (水) 15:20:54 | 最終更新:2011-04-20 (水) 17:56:20

配列のコピー を調べててよくわからなかったので
あれこれ実験してみた。

【環境】
J2SE6
Android 1.6

 

代入演算子
[android]// 1次元配列
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] うん、間違いなくシャローコピー(参照渡し)だね。 😎
 

for ステートメント
[android]// 1次元配列
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] うんうん、間違いなくディープコピー(値渡し)だね。 😎  

clone メソッド
[android]// 1次元配列
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次元配列 ・・・ ディープコピー(値渡し)
多次元配列 ・・・ シャローコピー(参照渡し)
 

arraycopy メソッド
[android]// 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 だから? 🙄  

copyOf メソッド
copyOfRange メソッド

Android は J2SE5 相当のため実証できず。

Posted by muchag | Java |
初回投稿:2011-04-20 (水) 15:20:54 | 最終更新:2011-04-20 (水) 17:56:20

コメントはまだありません »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment