配列コピーの検証

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

SimpleDateFormat

Posted by muchag | Java |
初回投稿:2011-04-19 (火) 20:16:28 | 最終更新:2011-04-19 (火) 20:42:28

日付のフォーマットと解析を、ロケールを考慮して行うための具象クラス。

JDK 6 ドキュメント:SimpleDateFormat

インスタンスの生成
  1. SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");

SimpleDateFormat()
SimpleDateFormat(String pattern)
SimpleDateFormat(String pattern, DateFormatSymbols formatSymbols)
SimpleDateFormat(String pattern, Locale locale)

JDK 6 ドキュメント:コンストラクタ

 

フォーマットの指定

インスタンス生成時にもちろんできるが
後から指定(変更)したい場合。

  1. SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
  2. sdf.applyPattern("MMM dd, yyyy");

void applyPattern(String pattern)

JDK 6 ドキュメント:applyPattern

 

日付クラスとの連携

日付クラスとしては Date が一般的なようだが
リファレンスを見ると、Date クラスは JDK 1.1 以降非推奨、となっている。
代わりに Calendar クラスの利用が推奨されている。

  1. Calendar calendar = Calendar.getInstance();
  2. SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
  3. System.out.printIn( sdf.format( calendar.getTime() ) );

Calendar

Posted by muchag | Java |
初回投稿:2011-04-19 (火) 20:16:28 | 最終更新:2011-04-19 (火) 20:42:28

可変長引数

Posted by muchag | Java |
初回投稿:2011-04-19 (火) 16:06:52 | 最終更新:2019-11-03 (日) 14:13:36

Flex のときに 関数パラメータ で大いに感動した記憶がある。
当然のように Java にもあった。
J2SE5 から導入されたとのこと。

概要

メソッドの引数が可変長になる。
つまり、引数の数を不定にできる。
 

原形(導入前)

元々は引数を配列にすることで対処していた。


String[] player;
player = {"甲子園", "豆タン"};
mizushimaManga(player):

player = {"山田", "里中", "岩鬼", "殿馬"};
mizushimaManga(player):

player = {"球道"};
mizushimaManga(player):

public void mizushimaManga(String[] player) {

	for (int i = 0; i < player.length; i++) {
		System.out.printIn(player[i]);
	}
}

これなら、引数の数がバラバラでも対処できる。

可変長引数

これを簡略化?したものが 可変長引数


mizushimaManga("甲子園", "豆タン"):
mizushimaManga("山田", "里中", "岩鬼", "殿馬"):
mizushimaManga("球道"):

public void mizushimaManga(String... player) {

	for (int i = 0; i < player.length; i++) {
		System.out.printIn(player[i]);
	}
}

5行目にある String... player の ... の部分が可変長引数の印。

仕様
  • 可変長なので引数の数は 0 でもよい
  • 他にも引数があるときは、最期に記述
  • 1つのメソッドで1種類しか使えない
  • メソッドがオーバーローディングされていて、
    引数が固定のメソッドと可変個のメソッドがマッチした場合、
    前者が優先される

 

可変長なので引数の数は 0 でもよい

mizushimaManga():

public void mizushimaManga(String... player) {

	for (int i = 0; i < player.length; i++) {
		System.out.printIn(player[i]);
	}
}

これでも機能する。
何も起こらないけど・・・。
player は length = 0 なのであって、null ではないことに注意。
 

他にも引数があるときは、最期に記述

mizushimaManga("男どアホウ甲子園", "南波高校", "甲子園", "豆タン"):
mizushimaManga("ドカベン", "明訓高校", "山田", "里中", "岩鬼", "殿馬"):

public void mizushimaManga(String title, String school, String... player) {

	for (int i = 0; i < player.length; i++) {
		System.out.printIn("「" + title + "」" + school + ":"+ player[i]);
	}
}
参考サイト

ひしだまのコンピュータ関連技術メモ:Java 可変長引数
TECHSCORE:6. 可変長引数

Posted by muchag | Java |
初回投稿:2011-04-19 (火) 16:06:52 | 最終更新:2019-11-03 (日) 14:13:36

配列

Posted by muchag | Java |
初回投稿:2011-04-19 (火) 12:40:34 | 最終更新:2011-04-20 (水) 18:21:45

Android を触っていて色々なサイトを巡ると
配列の表記方法が異なる。
なんじゃろ・・・。

グーグル先生! 質問です!
→ Java の道:1.配列の基本
→ ひしだまのコンピュータ関連技術メモ:JavaJava 配列

結果、元々2通りの宣言方法があることがわかった。
他にもルールがあるようなので、一応まとめておく。
 

宣言
  1. int myInt[];
  2. int[] myInt;

この2種類がある。

個人的には1行目の方がピンとくるのだが
Java では2行目が推奨のようなので、私はそちらを採用。
 

オブジェクト配列

オブジェクトも配列化できる。

  1. String[] myString;

 
UI も配列化可能。

  1. Button[] myButton;

あ、これは Android の話かな。
Java 本家はいじってないのでわからない。
 

インスタンスの生成(領域確保)

Java で配列を利用する場合は、インスタンスの生成と同時に領域を確保 しなければならない。
つまり 利用前 に領域を確保しなければならない。

  1. // まず宣言し
  2. int[] myInt;
  3. // インスタンスの生成と同時に領域を確保(利用前に領域確保)
  4. myInt = new int[3];
  5. // 利用
  6. myInt[0] = 2011;
  7.  
  8. // 宣言と同時にインスタンスの生成
  9. int myInt = new int[3];

int[3] の 3 は、3箇所確保 という意味なので
上記の例の場合は

  • myInt[0]
  • myInt[1]
  • myInt[2]

の領域を確保したことになる。
 

初期化
  1. int[] myInt;
  2. myInt = new int[] {1, 2, 3};
  3. myInt = {1, 2, 3}; // new int[] は省略可能
  4. String[] myString;
  5. myString = new String[] {"A", "B", "C"};
  6. myString = {"A", "B", "C"}; // new String[] は省略可能
  7.  
  8. // 宣言と同時に初期化も可能
  9. int[] myInt = new int[] {1, 2, 3};
  10. int[] myInt = {1, 2, 3}; // new int[] は省略可能
  11. String[] myString = new String[] {"A", "B", "C"};
  12. String[] myString = {"A", "B", "C"}; // new String[] は省略可能

こんな感じ。

{1, 2, 3} や {“A”, “B”, “C”} の部分を 配列初期化子 という。
 

仕様

「あれ? 3箇所確保したからって、キーは 0, 1, 2 で決定?
2, 5, 8 とかは? 連想配列は?」
すぐにこのような疑問を持った。

現段階で理解した限りでは
これが Java の仕様らしい。

  • 3箇所領域確保 = キーは 0, 1, 2 で決定
  • 要素数は固定
  • 連想配列というものは存在しない
  • 初期値が存在する(一般変数の場合は初期値なし)

 

連想配列

もし連想配列を利用したければ、クラスを自作することになるようだ。
キーワード:Hashtable, HashMap, TreeMap
<参考サイト>
オサレマの技術メモ:JAVAプログラム 連想配列操作
japan.internet.com:Javaで作成する多次元配列操作ライブラリ
 

多次元配列
  1. int[][] myInt = new int[3][2];

このようにすると、以下のような6つの領域が確保される。

  • myInt[0][0]
  • myInt[0][1]
  • myInt[1][0]
  • myInt[1][1]
  • myInt[2][0]
  • myInt[2][1]

 

  1. int[] myInt = new int[3];
  2. int[] myInt[0] = new int[2];
  3. int[] myInt[1] = new int[1];
  4. int[] myInt[2] = new int[3];

このようにすると、同じ多次元配列でも
2階層目の要素数が異なる多次元配列を生成できる。

と思ったら、こんなエラーが出た。

トークン “0” に構文エラーがあります。このトークンを削除してください Java 問題
型の不一致: int[] から int[][] には変換できません Java 問題
重複ローカル変数 myInt Java 問題

できないのかぁ。
 
正しい書式はこちら。

  1. int[][] myInt = new int[3][];
  2. myInt[0] = new int[2];
  3. myInt[1] = new int[1];
  4. myInt[2] = new int[3];
  • myInt[0][0]
  • myInt[0][1]
  • myInt[1][0]
  • myInt[2][0]
  • myInt[2][1]
  • myInt[2][2]

 

初期値
配列型 初期値
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char ‘\u0000’
boolean false
参照型(オブジェクト型) null

引用元サイト:Java の道 1.配列の基本
 

for ステートメント

配列(とコレクション)に特化した for ステートメント がある。

  1. // 配列の生成
  2. int[] myInt = {1, 2, 3};
  3.  
  4. // for (要素を受け取る変数: 配列)
  5. for (int i: myInt) {
  6.     System.out.println(i);
  7. }

5行目 ( ) 内は、: (コロン)であって ; (セミコロン)ではない。
 

length

length プロパティは、配列の要素数を返す。

  1. int[] myOdd = {1, 3, 5};
  2. System.out.printIn(myOdd.length);
  3.  
  4. // output
  5. // 3

 

ダンプ

配列の中身を見るには

  • 1次元配列 ・・・ Arrays.toString メソッド
  • 多次元配列 ・・・ Arrays.deepToString メソッド

 

  1. // 1次元配列
  2. int[] intArray = {1, 2, 3, 4, 5};
  3. Log.i("Dump", Arrays.toString(intArray) );
  4. // [1, 2, 3, 4, 5]
  5.  
  6. // 3次元配列
  7. int[][][] intMultidimensionalArray = { { {1, 2, 3, 4, 5}, {6, 7, 8} }, { {11, 21, 31}, {41, 51, 61, 71, 81} } };
  8. Log.i("Dump", Arrays.deepToString(intMultidimensionalArray) );
  9.  
  10. // [[[1, 2, 3, 4, 5], [6, 7, 8]], [[11, 21, 31], [41, 51, 61, 71, 81]]]

static String toString(int[] a)
各データ型毎に用意されている。

JDK 6 ドキュメント:Arrays toString

static String deepToString(Object[] a)

JDK 6 ドキュメント:Arrays deepToString

 

コピー

配列をコピーするには、以下の6種の手法がある。

  • 代入演算子 =
  • for ステートメント
  • Object.clone メソッド
  • System.arraycopy メソッド
  • Arrays.copyOf メソッド ← JDK 1.6 より追加
  • Arrays.copyOfRange メソッド ← JDK 1.6 より追加

コピーする際、コピー先配列について、基本的に

  • コピー元より要素数が少ない場合は、足りない要素はカットされる
  • コピー元より要素数が多い場合、もしくは情報がない場合は null がセットされる

 

代入演算子
  1. int[] myOdd = {1, 3, 5, 7, 9, 11};
  2. int[] myOdd2 = myOdd;

わかりやすいw
 

for ステートメント
  1. int[] myOdd = {1, 3, 5, 7, 9, 11};
  2. int[] myOdd2 = new int[myOdd.length];
  3.  
  4. for (int i = 0; i < myOdd.length; i++) {
  5.     myOdd2[i] = myOdd[i];
  6. }[/java2se6]
  7.  
  8. <div class="flow2">clone メソッド</div>
  9. [java2se6]int[] myOdd = {1, 3, 5, 7, 9, 11};
  10. int[] myOdd2 = (int[]) myOdd.clone();

protected Object clone()

JDK 6 ドキュメント:Object clone

これは単純で素敵。
 

arraycopy メソッド
  1. int[] myOdd = {1, 3, 5, 7, 9, 11};
  2. int[] myOdd2 = new int[5];
  3.  
  4. System.arraycopy(myOdd, 1, myOdd2, 3, 2);

static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

JDK 6 ドキュメント:System arraycopy

第1引数:コピー元配列
第2引数:コピー元配列開始位置
第3引数:コピー先配列
第4引数:コピー先配列開始位置
第5引数:コピー個数

myOdd2 の中身は、以下のようになる。

  • myOdd2[0] → 0
  • myOdd2[1] → 0
  • myOdd2[2] → 0
  • myOdd2[3] → 3
  • myOdd2[4] → 5

arraycopy メソッドは、その引数を見てもわかる通り、
配列を Object クラスで認識するため、データ型があいまいになる。
(このようにクラスを親クラスとして捉えることを ダウンキャスト というらしい)
 

copyOf メソッド
  1. int[] myOdd = {1, 3, 5, 7, 9, 11};
  2. int[] myOdd2 = Arrays.copyOf(myOdd, myOdd.length);

public static int[] copyOf(int[] original, int newLength)
各データ型毎に定義されている。

JDK 6 ドキュメント:Arrays copyOf

第1引数:コピー元配列
第2引数:コピー元から取り出す要素数(キー 0 からいくつ分か)
 

copyOfRange メソッド
  1. int[] myOdd = {1, 3, 5, 7, 9, 11};
  2. int[] myOdd2 = Arrays.copyOfRange(myOdd, 1, 4);

public static int[] copyOfRange(int[] original, int from, int to)
各データ型毎に定義されている。

JDK 6 ドキュメント:Arrays copyOfRange

第1引数:コピー元配列
第2引数:コピー元配列開始位置
第3引数:コピー元配列終了位置

このような仕様なのだが、ちょっと勘違いしそうな点がある。
開始位置はそのままなのでいいとして
終了位置は、その手前まで という意味である。

つまり、上の例では
{1, 3, 5, 7, 9, 11} のキー 1 からキー 4 の 手前まで なので
{3, 5, 7} となり、myOdd2 の中身は、以下のようになる。

  • myOdd2[0] → 3
  • myOdd2[1] → 5
  • myOdd2[2] → 7

 

複製手法の差異

手法には前述の通り3種あるが
その違いは何か。

arraycopy メソッドは、まぁ、明らかに違うとして
for ステートメントと clone メソッドの違いは何かというと
値渡しか参照渡しかの差。

  • 値渡し・・・ディープコピー (Deep Copy)
    for ステートメント、1次元配列の clone メソッド
  • 参照渡し・・・シャローコピー (Shallow Copy)
    代入演算子、多次元配列の clone メソッド

というらしい。

arraycopy メソッドについては、多くのサイトでシャローコピーであると書いてあるが
私の実験結果ではディープコピーであった。なんでだろ。
配列コピーの検証

参考元サイトによると

forループを使用した場合はループ内の実装方法の違い
(新たなインスタンスを生成するか(ディープ)、
代入演算子=によりコピーを行うか(シャロー)。)
によりディープコピーにもなりますし、シャローコピーにもなります。
どちらの方法を使用するかはケースにより異なります。

引用元サイト:Java の道:2.配列のコピー 配列のコピーの注意点

copyOf, copyOfRange メソッドについては、Android が J2SE5 相当のため実験できず。
コピー方式についても不明。

またそのうち実験してみよう。

Posted by muchag | Java |
初回投稿:2011-04-19 (火) 12:40:34 | 最終更新:2011-04-20 (水) 18:21:45

起動設定

Posted by muchag | L2j Server |
初回投稿:2011-04-18 (月) 22:49:56 | 最終更新:2011-04-18 (月) 22:49:56

  1. hosts の書き換え
  2. 自分の system フォルダを渡す
  3. 本物の system フォルダと置き換え
  4. bat ファイルの SC をデスクトップへ
Posted by muchag | L2j Server |
初回投稿:2011-04-18 (月) 22:49:56 | 最終更新:2011-04-18 (月) 22:49:56

1つ目のテキストの位置がずれる

Posted by muchag | Android,困ったTT |
初回投稿:2011-04-18 (月) 15:22:27 | 最終更新:2011-04-18 (月) 15:24:59

またまたわけのわからない現象が・・・。 🙄

RadioButton & RadioGroup
スクリプトでラジオボタンを配置しようとサンプルを作っていたら
1つ目のラジオボタンだけテキストの位置がずれる。

 
順番を入れ替えても
やはり1つ目のテキストの位置がずれる。

 

main.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:id="@+id/llMain"
  4.     android:orientation="vertical"
  5.     android:layout_width="fill_parent"
  6.     android:layout_height="fill_parent"
  7.     >
  8. </LinearLayout>

 

Acha.java
  1. package com.example.sample;
  2.  
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5. import android.view.ViewGroup;
  6. import android.widget.LinearLayout;
  7. import android.widget.RadioButton;
  8. import android.widget.RadioGroup;
  9.  
  10. public class Acha extends Activity {
  11.     /** Called when the activity is first created. */
  12.     @Override
  13.     public void onCreate(Bundle savedInstanceState) {
  14.         super.onCreate(savedInstanceState);
  15.         setContentView(R.layout.main);
  16.        
  17.         LinearLayout llMain = (LinearLayout) findViewById(R.id.llMain);
  18.        
  19.         RadioGroup rg = new RadioGroup(this);
  20.         llMain.addView(rg, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) );
  21.        
  22.         RadioButton rbA = new RadioButton(this);
  23.         rbA.setText("A");
  24.         rg.addView(rbA);
  25.        
  26.         RadioButton rbB = new RadioButton(this);
  27.         rbB.setText("B");
  28.         rg.addView(rbB);
  29.        
  30.     }
  31. }

グーグル先生におうかがいを立てても
上手くヒットしない。

たまにエミュレータの画面のサイズ?解像度?が
突然変わることがあると、エミュレータの再起動で直るんだけど
再起動しても直らない。

何事?

Posted by muchag | Android,困ったTT |
初回投稿:2011-04-18 (月) 15:22:27 | 最終更新:2011-04-18 (月) 15:24:59

RadioButton & RadioGroup

Posted by muchag | Android |
初回投稿:2011-04-18 (月) 13:34:36 | 最終更新:2011-04-18 (月) 15:55:05

毎度お馴染みの UI である RadioButton

HTML のように name 属性にてグループを構成するのではなくて
RadioGroup クラスにて設定する。

Android Developers:RadioButton & RadioGroup

レイアウト
XML
  1. <RadioGroup
  2.     android:id="@+id/radiogroup"
  3.     android:layout_width="fill_parent"
  4.     android:layout_height="wrap_content">
  5.  
  6.     <RadioButton
  7.         android:id="@+id/radiobuttonA"
  8.         android:text="A"
  9.         android:layout_width="wrap_content"
  10.         android:layout_height="wrap_content" />
  11.  
  12.     <RadioButton
  13.         android:id="@+id/radiobuttonB"
  14.         android:text="B"
  15.         android:layout_width="wrap_content"
  16.         android:layout_height="wrap_content" />
  17.  
  18.     <RadioButton
  19.         android:id="@+id/radiobuttonC"
  20.         android:text="C"
  21.         android:layout_width="wrap_content"
  22.         android:layout_height="wrap_content" />
  23. </RadioGroup>

 

スクリプト
  1. LinearLayout llMain = (LinearLayout) findViewById(R.id.llMain);
  2.  
  3. RadioGroup rg = new RadioGroup(this);
  4. llMain.addView(rg, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) );
  5.  
  6. RadioButton rbA = new RadioButton(this);
  7. rbA.setText("A");
  8. rg.addView(rbA);
  9.  
  10. RadioButton rbB = new RadioButton(this);
  11. rbB.setText("B");
  12. rg.addView(rbB);
  13.  
  14. RadioButton rbC = new RadioButton(this);
  15. rbB.setText("C");
  16. rg.addView(rbC);

8,12,16行目の addView は、4行目の addView とは異なり
RadioGroup 特有のもの。

void | addView (View child, int index, ViewGroup.LayoutParams params)

Android Developers:RadioGroup addView

第1引数:ラジオボタンのインスタンス
第2引数:ラジオボタンのポジション。省略可。記述する場合は 0 から順にしないとエラーになる
第3引数:LayoutParams。省略可

とひとまず動くには動いたけど
1つ目のテキストの位置がずれる
こんな問題を抱える羽目に。
 

注意点

RadioButton は RadioGroup の直下に配置すべし

ラジオボタンをグループ化するのは
ラジオボタンとはもともと択一式の UI なわけで
1つを選択したら、残りのものを OFF にするためである。

グループ化することで、残りがどれかを判断できる、という仕組み。

そこで1つ罠に落ちたのは
RadioButton は RadioGroup の 直下に配置しない
この グループが機能しない ということ。

私がやったのはこんな感じ。

  1. <RadioGroup>
  2.  
  3.     <LinearLayout>
  4.         <RadioButton>
  5.         <TextView>
  6.     </LinearLayout>
  7.  
  8.     <LinearLayout>
  9.         <RadioButton>
  10.         <TextView>
  11.     </LinearLayout>
  12.  
  13.     <LinearLayout>
  14.         <RadioButton>
  15.         <TextView>
  16.     </LinearLayout>
  17. </RadioGroup>

これでグループが機能しなくなった。

Posted by muchag | Android |
初回投稿:2011-04-18 (月) 13:34:36 | 最終更新:2011-04-18 (月) 15:55:05

setVisibility & getVisibility

Posted by muchag | Android |
初回投稿:2011-04-17 (日) 22:29:19 | 最終更新:2011-04-17 (日) 22:32:11

UI の表示・非表示を切り替えるメソッド。

Android Developers:View setVisibility & getVisibility

スクリプト
  1. Button button = (Button) findViewById(R.id.button);
  2.  
  3. // 表示する場合
  4. button.setVisibility(View.VISIBLE);
  5.  
  6. // 非表示にする場合(見えないけど、ボタン分のスペース空き)
  7. button.setVisibility(View.INVISIBLE);
  8.  
  9. // 非表示にする場合(ボタン分のスペース詰め)
  10. button.setVisibility(View.GONE);
  11.  
  12. // 値を取得する場合
  13. if (button.getVisibility == View.VISIBLE) {
  14. }
  15. else if (button.getVisibility == View.INVISIBLE) {
  16. }
  17. else if (button.getVisibility == View.GONE) {
  18. }

 

XML
  1. <!-- 表示 -->
  2. <Button android:visibility="visible" />
  3.  
  4. <!-- 非表示(ボタン分のスペース空き) -->
  5. <Button android:visibility="invisible" />
  6.  
  7. <!-- 非表示(ボタン分のスペース詰め) -->
  8. <Button android:visibility="gone" />

Android Developers:View android:visibility

Posted by muchag | Android |
初回投稿:2011-04-17 (日) 22:29:19 | 最終更新:2011-04-17 (日) 22:32:11

Add-on -> セッションマネージャ

Posted by muchag | Firefox,Library & PlugIn & AddIn |
初回投稿:2011-04-17 (日) 20:57:54 | 最終更新:2016-05-15 (日) 16:15:29

Firefox長い間苦労してきた Firefox のクラッシュ問題。
私はタブをいっぱい開きすぎるのよねぇ。
ウィンドウも多いと 25 とか・・・。

これでは Firefox さんも悲鳴を上げちゃうよね。

あんまり便利にしちゃうと、よその環境でやり辛くなるのが嫌で
今までアドオンを避けてきたんだけど
いよいよ困り果てて、アドオンを入れてみようと思いついた。

セッションマネージャ 0.7.5

入れてビックリ、めっさ便利だった。
 

インストール

上記リンク先からインストール。
 
インストール後は
[ツール]-[セッションマネージャ] から利用できる。

左の画像は、色々と設定後撮影して手直ししたので
デフォルトとは少し違うかも。

 

ウインドウ単位でセッションを保存

私は大概ウインドウ単位でネタを揃えている(普通か・・・)ので
ウィンドウ単位で保存したり復活させたりできるものを探した。

上記メニューから
[現在のウインドウを保存] を選択すると、複数タブをセットしたウインドウ丸ごと保存してくれる。

後は、再度メニューを表示し、
先ほど保存したウインドウ名を選択すれば・・・
がーん!!
他のウインドウが全部消えた・・・。 🙄

1つ元に戻す

メニューから
[バックアップセッション] で、元にもどった。 ホッ。

現在のウインドウに追加して保存したウインドウを開く

メニューから
[セッションマネージャオプション] で、左のダイアログが開く。

[保存と復元] タブを開き
[セッションを復元] の「既存のウインドウを取り替える」のチェックを外す。

これで先行のウインドウを閉じることなく
保存ウインドウが追加される。

 

全ウインドウ全タブ保存

セッション っていうのは、開始から終了までの一連の所作のこと。
つまり現在の全体の状態。

というわけで、「セッションの保存」とは
全ウインドウ全タブの保存ということになる。。

よって、メニューより
[セッションの保存] を選択。
左図真ん中ペインに全ウインドウ全タブが表示されるので
取捨選択ができる。

名前は自由に決められるし
「グループ」を作成して、フォルダ整理もできる。

グループは最初は設定されていないので
ドロップダウンに直接書き込む。

Posted by muchag | Firefox,Library & PlugIn & AddIn |
初回投稿:2011-04-17 (日) 20:57:54 | 最終更新:2016-05-15 (日) 16:15:29

ディレクトリ構成

Posted by muchag | Android |
初回投稿:2011-04-17 (日) 0:50:31 | 最終更新:2011-07-06 (水) 16:40:15

まだまだ理解できない
Android プロジェクトのディレクトリ構成。

デフォルト

[ファイル]-[新規]-[プロジェクト] から新しくプロジェクトを作成すると
左のようなフォルダ構成になっている。
新規プロジェクトの立ち上げ

 

src/

.java ファイルの格納場所。
パッケージ名が上位にあるところを見ると
Flex のときのようにパッケージを複数配置できるのかしら。
 

gen/

R.java の格納場所。

R.java には、リソースファイル群に付加した ID の一覧が書かれている。
コンパイル時?に自動的に書き加えられていく。
 

assets/

テキストファイルなどの自作ファイルの置き場所・・・らしい。

現時点ではまだまだ不明。
res/raw ディレクトリとの差異も不明。
 

res/

リソース格納場所。
Android Developers:Application Resources
Android Developers:Resource Types
 

res/drawable/

Android Developers:Providing Resources Grouping Resource Types
Android Developers:Drawable Resources
 
.png, .jpg, .gif などのビットマップファイルまたは XML ファイル置き場。

  • Bitmap files
  • Nine-Patches (re-sizable bitmaps)
  • State lists
  • Shapes
  • Animation drawables (Frame Animation)
  • Other drawables

drawable フォルダは、端末の Density ( dpi ) の判別してくれる。

しかし、Android OS のヴァージョン( API Level )によって異なる。
Android Developers:Supporting Multiple Screens

Android 1.5 (API Level 3)以前

drawable (160dpi 端末)
 

Android 1.6 (API Level 4)以降

drawable-ldpi (120dpi 端末)
drawable-mdpi (160dpi 端末)
drawable-hdpi (240dpi 端末)
drawable-nodpi (端末に対応するためにリサイズして欲しくないファイルの置き場)
 

Android 2.2 (API Level 8)以降

rawable-xhdpi (320dpi 端末)
 

Android 2.3 (API Level 9)以降

xlargeScreen に対応
 

<supports-screens>

AndroidManifest.xml に設定を行うことで
マーケットに端末でアクセスした場合に
当該端末が対応しているか否かを判別し
表示されるかどうか決まるらしい。

Android 1.6 以降ではデフォルトで全部 true だそうな。

  1. <supports-screens
  2.     android:resizeable=["true" | "false"]
  3.     android:smallScreens=["true" | "false"]
  4.     android:normalScreens=["true" | "false"]
  5.     android:largeScreens=["true" | "false"]
  6.     android:xlargeScreens=["true" | "false"]
  7.     android:anyDensity=["true" | "false"] />

Android Developers:<supports-screens>

単位 も参考にせよ。
 

識別子

また、res/drawable/ を res/drawable-ja/ とすることで、
端末に日本語設定がされているときに優先的にこちらを読ませることもできる。
詳しくは、アプリの多言語対応リソースファイルのネーミング
 

res/layout/

アクティビティのレイアウト XML ファイル置き場。
 

res/values/

Android Developers:Providing Resources Grouping Resource Types

以上のような、各種設定 XML ファイル置き場。
 

その他の決められたディレクトリ

Android Developers:Providing Resources Grouping Resource Types
 

res/anim/

トゥウィーンアニメーションを定義した XML ファイル置き場。
Android Developers:Animation Resources
 

res/color/

カラーステートリストを定義した XML ファイル置き場。
Android Developers:Color State List Resource
 

res/menu/

オプションメニュー、コンテキストメニュー、サブメニューなどの
アプリケーションメニューを定義した XML ファイル置き場。
Android Developers:Menu Resource
 

res/raw/

音楽データや画像データなどの自由なファイルの置き場。
コンパイルせずにアプリケーションに組み込みたい場合に利用。
 

res/xml/

独自の XML ファイル置き場。
あれこれサイトを見て回るとウィジェットなどを含む
アプリ設定画面に用いられることが多いようだ。
 

assets/ と res/raw/ の差異

参考サイト元にまとめてみると
 

assets/
  • アプリからの保存可
  • ファイル名制限なし
  • リソース ID なし
  • ディレクトリ管理あり(配下にフォルダを設置できる)
  • URL【file:///android_asset/】でアクセスできる
    (コロンの後ろの / スラッシュは3本である)

 

assets/hoge.txt
  1. AssetManager as = getResources().getAssets();
  2. InputStream stream_in = as.open("hoge.txt");

 

assets/hoge.png
  1. WebView webView = (WebView) findViewById(R.id.web);
  2. String strHtml = "<html><head><title>Test</title></head><body><img src='hoge.png' /></body></html>";
  3. webView.loadDataWithBaseURL("file:///android_asset/", strHtml, "text/html", "utf-8", null);

 

res/raw/
  • アプリからの保存不可
  • ファイル名制限あり([a-z] 英小文字、 _ アンダースコア、. ピリオドのみ)
  • リソース ID あり(R.raw.hoge)
  • ディレクトリ管理なし(配下にフォルダを設置でない)
  • drawable 同様に raw-ja, raw-mdpi などとネーミングすることで
    自動判別機能を利用できる

 

res/raw/hoge.png
  1. Resources resources = this.getResources();  
  2. InputStream inputStream = res.openRawResource(R.raw.hoge);

 
<参考元サイト>
Y05_net’s blog:Androidアプリにおけるassetsフォルダとres/rawの使い分け
整理できない底辺プログラマのメモブログ:任意データの置き場所は、/assets or /res/raw?
tappli blog:[Android] assetsのファイルを使う

Posted by muchag | Android |
初回投稿:2011-04-17 (日) 0:50:31 | 最終更新:2011-07-06 (水) 16:40:15
« 前ページへ次ページへ »