この記事では、当社 の新人エンジニア研修の参考にJava8を解説します。
前回は繰り返し処理について解説しました。
コンピュータのすごさがあたらめて感じられたのではないでしょうか?
今回は配列の作成と使用について解説します。
これまで学んだとおり、プログラムでは基本的に変数に値を入れて処理をしていくのでした。
では、変数が10個、20個、100個と増えていったらどうなるでしょうか?
名前を付けるだけでも大変ですね。
そんな時に便利なのが配列です。
配列のイメージは複数の値を入れる入れ物(変数)が並んだものです。
1.配列の使い方
1.配列を表す変数を宣言します
int[] ages;
データ型の後の[](ブラケット)が単なる変数ではなく配列であることを表しています。
参考までに以下のように[]を変数名の後ろに書く書き方を目にすることもあるかもしれません。
int ages[];
これはC/C++ 言語ではこのような書き方をするためです。Javaに移った技術者に違和感のないようにという配慮ですので、皆さんは、データ型の後に[]を入れる書き方を身に着けてください。
2.配列の要素を確保します。[]の中の数値が要素数を表します。
ages = new int[3];
ここでは、new演算子というものが使われています。
new演算子はJavaでインスタンス化(実体化)を行う際に使われるものです。
インスタンスについては後述します。
3.インデックスを用いて要素を指定し、配列に値を入れていきます。
ages[0] = 10;
ages[1] = 20;
ages[2] = 51;
このときインデックスは0から始まるので、0,1,2とインデックスは2までしかないことに注意しましょう。
インデックスは0~(要素数-1)
4.配列に入っている値をインデックスを用いて参照します。
System.out.println(ages[2]);
上記の例をサンプルコードにしてみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package chap06; public class Example01 { public static void main(String[] args) { int ages[]; ages = new int[3]; ages[0] = 10; ages[1] = 20; ages[2] = 51; for (int i = 0; i < 3; i++) { System.out.println(ages[i]); } } } |
<結果>
10 20 51 |
この例では、配列の要素を繰り返しによって表示させています。このように、配列とfor文は相性が良いです。
また、配列の大きさ(要素の数)は次のようにして確認できます。
変数名.length
※ここでlengthは配列のフィールドであってメソッドではない点に着目ください。実はこのようにフィールドに直接アクセスできるということはJavaでは大変珍しいことです。
また、カプセル化のところでお話ししたいと思います。
変数名.lengthという表現を使えば、上記のfor文は以下のようにも書けます。
for (int i = 0; i < ages.length; i++) {
System.out.println(ages[i]);
}
マジックナンバーが消えて意味が分かりやすく、また変更に強いプログラムになりました。
また、以下のように配列を一度に初期化する方法もあります。
1 2 3 4 5 6 7 8 9 10 11 12 |
package chap06; public class Example02 { public static void main(String[] args) { int[] ages = {10, 20, 51}; for (int i = 0; i < ages.length; i++) { System.out.println(ages[i]); } } } |
<結果>は今までと同じ。
この場合には、3という要素数は自動で決まります。
2.ArrayIndexOutOfBoundsException
以下のように配列の要素を3つ確保すると
ages = new int[3];
インデックスは0から始まるので、0,1,2の3つの要素が用意されるのでした。
では、以下のように存在しない要素を指定すると何が起こるでしょうか?
1 2 3 4 5 6 7 8 9 10 |
package chap06; public class Example03 { public static void main(String[] args) { int ages[]; ages = new int[3]; ages[3] = 10; } } |
私の環境では、以下のようなメッセージが出てプログラムの実行が中断されました。
Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 3 at Example27_4.main(Example27_4.java:7) |
このように存在しない要素にアクセスしようとした場合は、ArrayIndexOutOfBoundsExceptionという例外が発生します。
このとても長い名前を持つ例外は、
Array(配列の)Index(インデックスが)OutOfBounds(範囲を超えた)Exception(例外)
という意味です。
これらのエラーメッセージにも意味がありますので、必ず、グーグルなどで調べるようにしてください。
目を背けてはいけません。
このとき前もってIDEが例外の発生を教えてくれたらいいのに、と思ったかもしれません。
しかし、詳しくは後述しますが、これは非チェック例外というものでコンパイルもチェックしてくれない例外です。
プログラマの責任で対処すべき例外なのです。
3.参照とハッシュ値
ところで、上記の例では、ages[0]には10が、ages[1]には20が、ages[2]には51が入っていました。
では、agesという変数には何が入っているのでしょうか?
System.out.println(ages);
としてみると、
[I@15db9742
私の環境では上記の文字列が表示されました。
この文字列はハッシュコードと呼ばれるものです。
データの置き場所であるメモリのアドレスだと思っていただければ大きく違ってはいません。
なお、先頭の “[ ”は配列であることを意味しています。
ここのところは後程プリミティブ型と参照型というテーマでまとめますので、ここでは、配列は参照型なんだという理解を持っておいてください。
4.toStringメソッドで配列の要素を見やすくする
標準出力に配列の要素を一度に表示するにはどうしたらよいでしょうか?
毎回、繰り返し処理を使って表示させるのもおっくうです。
そんな時に便利なのが配列の要素を文字列化してくれるArraysクラスのtoStringメソッドです。
Arraysは配列という意味の英語。
to(へ)、String(文字列)ということで、名が体を表すネーミングですね。
1 2 3 4 5 6 7 8 9 10 11 |
package chap06; import java.util.Arrays; public class Example04 { public static void main(String[] args) { int[] ages = {10, 20, 51}; System.out.println(Arrays.toString(ages)); } } |
<結果>は今までと同じ。
※パッケージ宣言とクラス宣言の間に「import java.util.Arrays;」という一文を挿入する必要があります。IDEを使うと簡単に挿入できますので講師に教わってください。
また、importの意味は、2回目の記事でお話ししました。
<結果>
[10, 20, 51] |
デバッグ時に便利ですので覚えておいてください。
5.拡張for文
配列と相性が良いのが拡張for文です。
拡張for文は、配列の先頭から最後までを連続して処理するときに簡潔に書ける構文です。
(一時変数の宣言 : 配列の変数)
初学者の方はforの()の中の変数宣言と配列の変数指定の順番を逆にしないように気をつけてください。
また、区切りは;(セミコロン)ではなく(:コロン)ですので間違えないようにしましょう。
サンプルコードで確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 |
package chap06; public class Example05 { public static void main(String[] args) { int[] ages ={10,20,51}; for (int age : ages) { System.out.println(age); } } } |
<結果>
10 20 51 |
このようにほんの少しですが短く書くことができました。
この拡張for文はのちにコレクションというものを学んだ時にも頻出しますので、今のうちに慣れておいてください。
繰り返し処理をするために一時的に(使い捨ての)変数ageを使っています。
以下はそのことを示すサンプルコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package chap06; public class Example06 { public static void main(String[] args) { int[] ages = {10, 20, 51}; for (int age : ages) { System.out.println(age); age *= 2; } for (int age : ages) { System.out.println(age); } } } |
<結果>
10 20 51 10 20 51 |
for文と比較した場合の拡張for文の制限は、必ず配列の先頭からの処理となることです。
後ろから処理をしたい場合は、直接対応できませんので、あらかじめ逆順にソートし直すなどの前処理が必要になります。
さらに、一つ飛ばしなどにしたい場合にはあまり向かないのでそのような時には通常のfor文を使った方が良いでしょう。
ここまで作成してきた配列は1列でしたので1次元配列と呼ばれます。
それに対して、2次元以上の配列を多次元配列といいます。
ここでは、2次元配列を見ていきましょう。
6.2次元配列
サンプルコードを見てみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package chap06; public class Example07 { public static void main(String[] args) { int[][] scores = { {100, 80, 90, 90}, {90, 90, 90, 90}, {60, 90, 80, 70},}; System.out.println(scores[0][3]); System.out.println(scores[2][3]); for (int[] score : scores) { for (int i : score) { System.out.print(i + ","); } } } } |
<結果>
90 70 100,80,90,90,90,90,90,90,60,90,80,70, |
11行目以降に拡張for文を入れ子にして使っています。
このようにシンプルに書けるのが拡張for文の良いところです。
2次元以降の配列について、研修では深入りしませんので、このサンプルコードを示すだけとします。
ここまで理解できたら、まとめとして演習問題にチャレンジしましょう。
今回はJavaの配列の作成と使用について見てきました。
次回は、文字と文字列の扱いを学んで、文字列も実は参照型であり、しかも、やや特殊な参照型だということについて学びましょう。
JavaSE8の解説に戻る