配列コピーの検証

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

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

【環境】
J2SE6
Android 1.6

 

代入演算子
  1. // 1次元配列
  2. int[] intArrayFrom = {1, 2, 3, 4, 5};
  3. int[] intArrayTo = intArrayFrom;
  4.  
  5. Log.i("From", Arrays.toString(intArrayFrom) );
  6. // [1, 2, 3, 4, 5]
  7. Log.i("To", Arrays.toString(intArrayTo) );
  8. // [1, 2, 3, 4, 5]
  9.  
  10. intArrayFrom[2] = 88;
  11.  
  12. Log.i("From", Arrays.toString(intArrayFrom) );
  13. // [1, 2, 88, 4, 5]
  14. Log.i("To", Arrays.toString(intArrayTo) );
  15. // [1, 2, 88, 4, 5]
  16.  
  17. intArrayTo[0] = 123;
  18.  
  19. Log.i("From", Arrays.toString(intArrayFrom) );
  20. // [123, 2, 88, 4, 5]
  21. Log.i("To", Arrays.toString(intArrayTo) );
  22. // [123, 2, 88, 4, 5]
  23.  
  24.  
  25.  
  26. // 2次元配列
  27. int[][] intMultidimensionalArrayFrom = { {1, 2, 3, 4, 5}, {6, 7, 8} };
  28. int[][] intMultidimensionalArrayTo = intMultidimensionalArrayFrom;
  29.  
  30. Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) );
  31. // [[1, 2, 3, 4, 5], [6, 7, 8]]
  32. Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) );
  33. // [[1, 2, 3, 4, 5], [6, 7, 8]]
  34.  
  35. intMultidimensionalArrayFrom[0][2] = 88;
  36.  
  37. Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) );
  38. // [[1, 2, 88, 4, 5], [6, 7, 8]]
  39. Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) );
  40. // [[1, 2, 88, 4, 5], [6, 7, 8]]
  41.  
  42. intMultidimensionalArrayTo[1][0] = 123;
  43.  
  44. Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) );
  45. // [[1, 2, 88, 4, 5], [123, 7, 8]]
  46. Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) );
  47. // [[1, 2, 88, 4, 5], [123, 7, 8]]

うん、間違いなくシャローコピー(参照渡し)だね。 😎
 

for ステートメント
  1. // 1次元配列
  2. int[] intArrayFrom = {1, 2, 3, 4, 5};
  3. int[] intArrayTo = new int[intArrayFrom.length];
  4.  
  5. for (int i = 0; i < intArrayFrom.length; i++) {
  6.  
  7.     intArrayTo[i] = intArrayFrom[i];
  8. }
  9.  
  10. Log.i("From", Arrays.toString(intArrayFrom) );
  11. // [1, 2, 3, 4, 5]
  12. Log.i("To", Arrays.toString(intArrayTo) );
  13. // [1, 2, 3, 4, 5]
  14.  
  15. intArrayFrom[2] = 88;
  16.  
  17. Log.i("From", Arrays.toString(intArrayFrom) );
  18. // [1, 2, 88, 4, 5]
  19. Log.i("To", Arrays.toString(intArrayTo) );
  20. // [1, 2, 3, 4, 5]
  21.  
  22. intArrayTo[0] = 123;
  23.  
  24. Log.i("From", Arrays.toString(intArrayFrom) );
  25. // [1, 2, 88, 4, 5]
  26. Log.i("To", Arrays.toString(intArrayTo) );
  27. // [123, 2, 3, 4, 5]
  28.  
  29.  
  30.  
  31. // 2次元配列
  32. int[][] intMultidimensionalArrayFrom = { {1, 2, 3, 4, 5}, {6, 7, 8} };
  33. int[][] intMultidimensionalArrayTo = new int[intMultidimensionalArrayFrom.length][];
  34.  
  35. for (int i = 0; i < intMultidimensionalArrayFrom.length; i++) {
  36.  
  37.     for (int j = 0; j < intMultidimensionalArrayFrom[i].length; j++) {
  38.  
  39.         intMultidimensionalArrayTo[i] = new int[intMultidimensionalArrayFrom[i].length];
  40.  
  41.         intMultidimensionalArrayTo[i][j] = intMultidimensionalArrayFrom[i][j];
  42.     }
  43. }
  44.  
  45. Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) );
  46. // [[1, 2, 3, 4, 5], [6, 7, 8]]
  47. Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) );
  48. // [[1, 2, 3, 4, 5], [6, 7, 8]]
  49.  
  50. intMultidimensionalArrayFrom[0][2] = 88;
  51.  
  52. Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) );
  53. // [[1, 2, 88, 4, 5], [6, 7, 8]]
  54. Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) );
  55. // [[1, 2, 3, 4, 5], [6, 7, 8]]
  56.  
  57. intMultidimensionalArrayTo[1][0] = 123;
  58.  
  59. Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) );
  60. // [[1, 2, 88, 4, 5], [6, 7, 8]]
  61. Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) );
  62. // [[1, 2, 3, 4, 5], [123, 7, 8]][/android]
  63. うんうん、間違いなくディープコピー(値渡し)だね。  :cool:
  64.  
  65. <div class="flow1">clone メソッド</div>
  66. [android]// 1次元配列
  67. int[] intArrayFrom = {1, 2, 3, 4, 5};
  68. int[] intArrayTo = (int[]) intArrayFrom.clone();
  69.  
  70. Log.i("From", Arrays.toString(intArrayFrom) );
  71. // [1, 2, 3, 4, 5]
  72. Log.i("To", Arrays.toString(intArrayTo) );
  73. // [1, 2, 3, 4, 5]
  74.  
  75. intArrayFrom[2] = 88;
  76.  
  77. Log.i("From", Arrays.toString(intArrayFrom) );
  78. // [1, 2, 88, 4, 5]
  79. Log.i("To", Arrays.toString(intArrayTo) );
  80. // [1, 2, 3, 4, 5]
  81.  
  82. intArrayTo[0] = 123;
  83.  
  84. Log.i("From", Arrays.toString(intArrayFrom) );
  85. // [1, 2, 88, 4, 5]
  86. Log.i("To", Arrays.toString(intArrayTo) );
  87. // [123, 2, 3, 4, 5]
  88.  
  89.  
  90.  
  91. // 2次元配列
  92. int[][] intMultidimensionalArrayFrom = { {1, 2, 3, 4, 5}, {6, 7, 8} };
  93. int[][] intMultidimensionalArrayTo = (int[][]) intMultidimensionalArrayFrom.clone();
  94.  
  95. Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) );
  96. // [[1, 2, 3, 4, 5], [6, 7, 8]]
  97. Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) );
  98. // [[1, 2, 3, 4, 5], [6, 7, 8]]
  99.  
  100. intMultidimensionalArrayFrom[0][2] = 88;
  101.  
  102. Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) );
  103. // [[1, 2, 88, 4, 5], [6, 7, 8]]
  104. Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) );
  105. // [[1, 2, 88, 4, 5], [6, 7, 8]]
  106.  
  107. intMultidimensionalArrayTo[1][0] = 123;
  108.  
  109. Log.i("From", Arrays.deepToString(intMultidimensionalArrayFrom) );
  110. // [[1, 2, 88, 4, 5], [123, 7, 8]]
  111. Log.i("To", Arrays.deepToString(intMultidimensionalArrayTo) );
  112. // [[1, 2, 88, 4, 5], [123, 7, 8]]

うっは、本当だったんだ・・・。

そもそも、こんな検証をしようとしたのは、参考元サイトに
「1次元配列と多次元配列で異なる」
と書いてあったのがきっかけ。

そんなアホな! と思った私は検証する気になった。

でも事実はこの通り・・・。
Object.clone() メソッドでは
1次元配列 ・・・ ディープコピー(値渡し)
多次元配列 ・・・ シャローコピー(参照渡し)
 

arraycopy メソッド

// 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