新人エンジニア研修で知っておきたい配列の作り方と使い方
なぜ、配列の理解が重要なのか、その理由。
この記事では、弊社の新人エンジニア研修の参考にJava8を解説します。
前回は繰り返し処理について解説しました。
コンピュータのすごさがあたらめて感じられたのではないでしょうか?
今回は配列の作成と使用について解説します。
これまで学んだとおり、プログラムでは基本的に変数に値を入れて処理をしていくのでした。
では、変数が10個、20個、100個と増えていったらどうなるでしょうか?
名前を考えるだけでも大変ですね。
そんな時に便利なのが配列です。
配列のイメージは同じ型の複数の値を入れる入れ物(変数)が並んだものです。(下図6.1参照)

目次
1.配列の使い方
1.配列を表す変数を宣言します。
int[] ages;
データ型の後の[](角カッコ)が単なる変数ではなく配列であることを表しています。
2.配列の要素を確保します。[]の中の数値が要素数を表します。
ages = new int[3]
new演算子というものが使われています。
new演算子はJavaでインスタンス化(実体化)を行う際に使われるものです。
インスタンスについては後述します。
しかし、この段階では配列の中身は0が詰められている状態です。(下図6.2参照)

3.添字を用いて要素を指定し、配列に値を入れていきます。
ages[0] = 10;
ages[1] = 20;
ages[2] = 51;
このとき添字は0から始まるので、0,1,2と添字は2までしかないことに注意しましょう。
配列の添字(index)は0~(要素数-1)
4.配列に入っている値を添字を用いて参照します。
System.out.println(ages[2]);
51が表示されます。
初学者に多い間違いは配列の添字(上記の2)と要素(上記の51)を混同することです。気をつけましょう。
サンプルコードにしてみました。
<結果を表示>
10
20
51
この例では、配列の要素を繰り返しによって表示させています。このように、配列とfor文は相性が良いです。
また、配列の大きさ(要素の数)は次のようにして確認できます。
変数名.length
変数名.lengthという表現を使えば、上記のfor文は以下のようにも書けます。
マジックナンバーが消えて意味が分かりやすく、また配列要素数の変更にも強いプログラムになりました。
さらに、以下のように配列を一度に初期化する方法もあります。
<結果>は先と同じ。
2.ArrayIndexOutOfBoundsException
以下のように配列の要素を3つ確保すると
ages = new int[3];
添字は0から始まるので、0,1,2の3つの要素が用意されるのでした。
では、以下のように存在しない要素を指定すると何が起こるでしょうか?
以下のようなメッセージが出てプログラムの実行が中断されました。
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 at chap06.Example03.main(Example03.java:8) C:\Users\owner\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1 ビルド失敗(合計時間: 0秒) |
このように存在しない要素にアクセスしようとした場合は、例外が発生します。
今回発生した例外は、ArrayIndexOutOfBoundsExceptionという名前です。
このとても長い名前を持つ例外は、
Array「配列の」Index「添字が」OutOfBounds「範囲を超えた」Exception「例外」
という意味です。
これらのエラーメッセージにも意味がありますので、知らないものに遭遇したときには必ず、グーグルなどで調べるようにしてください。
目を背けてはいけません。
このとき「前もってIDEが例外の発生を教えてくれたらいいのに」と思ったかもしれません。
しかし、詳しくは例外のところで後述しますが、この例外はコンパイラがチェックしてくれない例外なのです。
コンパイラがチェックしてくれないので非チェック例外といいます。
3.参照とハッシュ値
ところで、上記の例では、ages[0]には10が、ages[1]には20が、ages[2]には51が入っていました。
では、agesという変数には何が入っているのでしょうか?
System.out.println(ages);
としてみると、
[I@15db9742
上記の文字列が表示されました。
この文字列の@以降はハッシュコードと呼ばれるものです。
データの置き場所であるメモリのアドレスだと思っていただければ大きく違ってはいません。
ちなみにこのハッシュはごちゃまぜにするという意味でハッシュドビーフ(hashed beef)などと同じ語源です。
なお、先頭の “[ ”は配列であることを意味しています。
ここまでのところを図解すると下図6.3のようになります。
①JVMが管理するメモリ領域には大きく分けてスタック領域とヒープ領域の2つがあります。
スタック領域はローカル変数やメソッドが格納される領域で、ヒープ領域はインスタンスが格納される領域です。

②メモリにはアドレスがあります。
ローカル変数に格納されるのは、配列が格納される予定のヒープ領域の先頭アドレス(ここでは15db9742)です。(下図6.4参照)

③要素がヒープ領域に格納されます。(下図6.5参照)

このような仕組みのため、
System.out.println(ages);
とすると以下の表示になるわけです。
[I@15db9742
なお、Javaの参照型は以下の3つに整理されます。
配列と、クラス(インスタンス)とインタフェースです。
例えば、次回学ぶ文字列はクラス型に分類できます。
4.配列の要素を一度に表示する
標準出力を使って配列の要素を一度に表示するにはどうしたらよいでしょうか?
毎回、繰り返し処理を使って表示させるのもおっくうです。
そんな時に便利なのが配列の要素を文字列化してくれるArraysクラスのtoStringメソッドです。
Arraysは「配列」という意味の英語です。
Arrays.toStringの意味はArrays「配列を」toString「文字列へ」ということで、名が体を表すネーミングですね。
※パッケージ宣言とクラス宣言の間に「import java.util.Arrays;」という一文を挿入する必要があります。IDEを使うと簡単に挿入できますので講師に教わってください。 また、importの意味は、2回目の記事でお話ししました。
<結果>
[10, 20, 51] |
5.拡張for文
配列と相性が良いのが拡張for文です。
拡張for文は、配列の先頭から最後までを連続して処理するときに簡潔に書ける構文です。
まずはイメージです。(下図6.6参照)
配列の要素を0番目から一つずつ一時的な変数に格納して処理します。

<構文>
(一時変数の宣言 : 配列の変数)
初学者の方はforの()の中の変数宣言と配列の変数指定の順番を逆にしないように気をつけてください。
また、区切りは;(セミコロン)ではなく(:コロン)ですので間違えないようにしましょう。
もっとも便利なIDEのコードテンプレートを使えば間違いないですが。
なお、この(:コロン)は「中の」といった程度の意味です。
サンプルコードで確認してみましょう。
<結果を表示>
10
20
51
このようにほんの少しですがシンプルに書くことができました。
この拡張for文はのちにコレクション(ArrayList)というものを学んだ時にも頻出しますので、今のうちに慣れておいてください。
繰り返し処理をするために一時的に“使い捨て”の変数ageを使っています。
以下はそのことを示すサンプルコードです。
配列の要素をそれぞれ2倍にしたつもりですが、できていません。
<結果を表示>
10
20
51
10
20
51
変数ageがローカル変数である以上、当然といえば当然ですが間違えやすいところです。
通常のfor文と比較した場合の拡張for文のメリットは、i,jなどの変数が不要になり、バグを作り込む可能性が低下することです。
一方、通常のfor文と比較した場合の拡張for文の制限は、必ず配列の先頭からの処理となることです。
配列の後ろから処理をしたい場合は、直接対応できません。
あらかじめ逆順にソートしておく前処理が必要になります。
さらに、要素の一つ飛ばしに処理を加えたい場合などにはあまり向かないでしょう。
そもそも配列やコレクションフレームワークが無ければ拡張for文は使えません。
したがって通常のfor文が不要になるわけではありませんが、拡張for文が使える場面では拡張for文を優先させて下さい。
特にこのあとコレクションフレームワークというものを学ぶと重宝します。
6.2次元配列
ここまで作成してきた配列は1列でしたので1次元配列と呼ばれます。
それに対して、2次元以上の配列を多次元配列といいます。
ここでは、2次元配列を見ていきましょう。
イメージとしてはエクセルの表に少し似ています。
ただし、下図6.7のように本当は1次元の配列を複数用意したものです。

サンプルコードを見てみます。
<結果を表示>
40
30
10,20,30,40,50,60,70,80,90,10,20,30,
このようにシンプルに書けるのが拡張for文の良いところです。
なお、このサンプルでは拡張for文を入れ子にしていましたね。
2次元以上の配列について、研修では深入りしませんので、このサンプルコードを示すだけとします。
7.配列とオブジェクト指向
なお、配列の利用場面はかつてほどではありません。
なぜなら、配列は要素数を後から変更できません。
また、型の異なるデータを同じ配列に入れることもできません。
これら配列の弱点を克服したArrayListについては後で学びましょう。
※例えば、Androidの正式開発言語となったKotlinはJavaの後継言語とも目されていますが、配列は存在せず、常にArrayクラスを使います。
昔は(といっても1990年代です)、オブジェクトという考え方がなく配列を使った処理を多用していました。
例えば、以下は5名の生徒の成績を管理するプログラムです。
<結果を表示>
Tom's score is 80
John's score is 75
Mary's score is 100
Ken's score is 90
Jimmy's score is 80
イメージは下図6.8の通りです。

しかし、現代では1人分のデータは1人分のオブジェクト(より正確にはインスタンス)として表現することが一般的です。
この点は何度も繰り返しお伝えしていくテーマなので、今は用語に慣れる程度で結構です。
今回はJavaの配列の作成と使用について見てきました。
次回は、文字と文字列の扱いを学んで、文字列も実は参照型であるということについて学びましょう。
<まとめ:隣の人に正しく説明できたらチェックを付けましょう>
□配列は同じ型の複数の変数が並んだものと考えられる
□配列の添字(index)は0~(要素数-1)である
□拡張for文は、配列の先頭から最後までを連続して処理するときに簡潔に書ける構文である
□参照にはハッシュコードが入っている
まとめができたら、アウトプットとして演習問題にチャレンジしましょう。
JavaSE8の解説に戻る
最後までお読みいただきありがとうございました。