ITエンジニアのプレイングマネージャー化応援サイト

6.配列の作成と使用

この記事では、弊社の新人エンジニア研修の参考にJava8を解説します。

前回は繰り返し処理について解説しました。

コンピュータのすごさがあたらめて感じられたのではないでしょうか?

今回は配列の作成と使用について解説します。

 

これまで学んだとおり、プログラムでは基本的に変数に値を入れて処理をしていくのでした。

では、変数が10個、20個、100個と増えていったらどうなるでしょうか?

名前を付けるだけでも大変ですね。

そんな時に便利なのが配列です。

 

配列のイメージは同じ型の複数の値を入れる入れ物(変数)が並んだものです

 

1.配列の使い方

1.配列を表す変数を宣言します

int[] ages;

データ型の後の[](角カッコ)が単なる変数ではなく配列であることを表しています。

2.配列の要素を確保します。[]の中の数値が要素数を表します。

ages = new int[3];

new演算子というものが使われています。

new演算子はJavaでインスタンス化(実体化)を行う際に使われるものです。

インスタンスについては後述します。

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が表示されます。

 

サンプルコードにしてみました。

<結果>

10
20
51

この例では、配列の要素を繰り返しによって表示させています。このように、配列とfor文は相性が良いです。

また、配列の大きさ(要素の数)は次のようにして確認できます。

変数名.length

変数名.lengthという表現を使えば、上記のfor文は以下のようにも書けます。

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つの要素が用意されるのでした。

では、以下のように存在しない要素を指定すると何が起こるでしょうか?

以下のようなメッセージが出てプログラムの実行が中断されました。

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)などと同じ語源です。

 

なお、先頭の “[ ”は配列であることを意味しています。

 

ここまでのところを図解すると以下のようになります。

①JVMが管理するメモリ領域には大きく分けてスタック領域とヒープ領域の2つがあります。

スタック領域はローカル変数やメソッドが格納される領域で、ヒープ領域はインスタンスが格納される領域です。

メモリ内の動作のイメージ①

メモリ内の動作のイメージ①

②メモリにはアドレスがあります。

ローカル変数に格納されるのは、配列が格納される予定のヒープ領域の先頭アドレスです。

メモリ内の動作のイメージ②

メモリ内の動作のイメージ②

③要素がヒープ領域に格納されます。

メモリ内の動作のイメージ③

メモリ内の動作のイメージ③

 

このような仕組みのため、

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文は、配列の先頭から最後までを連続して処理するときに簡潔に書ける構文です。

<構文>

(一時変数の宣言 : 配列の変数

初学者の方はforの()の中の変数宣言と配列の変数指定の順番を逆にしないように気をつけてください。

また、区切りは;(セミコロン)ではなく(:コロン)ですので間違えないようにしましょう。

もっとも便利なIDEのコードテンプレートを使えば間違いないですが。

なお、この(:コロン)は「中の」といった程度の意味です。

サンプルコードで確認してみましょう。

<結果>

10
20
51

このようにほんの少しですがシンプルに書くことができました。

この拡張for文はのちにコレクション(ArrayList)というものを学んだ時にも頻出しますので、今のうちに慣れておいてください。

繰り返し処理をするために一時的に“使い捨て”の変数ageを使っています。

この変数の値を繰り返し処理の中で変更しても元の配列には影響しませんので注意してください。

このageがローカル変数である以上、当然といえば当然ですが。

以下はそのことを示すサンプルコードです。

配列の要素自体を2倍にしたつもりですが、できていません。

<結果>

10
20
51
10
20
51

<拡張for文のイメージ>

一時的な変数に格納している拡張for文のイメージ

 

通常のfor文と比較した場合の拡張for文のメリットは、i,jなどの変数が不要になり、バグを作り込む可能性が低下することです。

一方、通常のfor文と比較した場合の拡張for文の制限は、必ず配列の先頭からの処理となることです。

配列の後ろから処理をしたい場合は、直接対応できません。

あらかじめ逆順にソートしておく前処理が必要になります。

さらに、要素の一つ飛ばしに処理を加えたい場合などにはあまり向かないでしょう。

したがって通常のfor文が不要になるわけではありませんが、拡張for文が使える場面では拡張for文を優先させて下さい。

 

6.2次元配列

ここまで作成してきた配列は1列でしたので1次元配列と呼ばれます。

それに対して、2次元以上の配列を多次元配列といいます。

ここでは、2次元配列を見ていきましょう。

イメジとしてはエクセルの表に少しだけ似ています。

ただし、以下の図のように本当は1次元の配列を複数用意したものです。

 

2次元配列の本当の姿

2次元配列の本当の姿

 

 

サンプルコードを見てみます。

<結果>

90
70
100,80,90,90,90,90,90,90,60,90,80,70,

なお、このサンプルでは拡張for文を入れ子にしています。

このようにシンプルに書けるのが拡張for文の良いところです。

2次元以上の配列について、研修では深入りしませんので、このサンプルコードを示すだけとします。

 

7.配列とオブジェクト指向

なお、配列の利用場面はかつてほどではありません。

なぜなら、配列は要素数を後から変更できません。

また、配列はオブジェクトではないため、メソッドを持たせることもできません。

これら配列の弱点を克服したArrayListについては後で学びましょう。

※例えば、Androidの正式開発言語となったKotlinはJavaの後継言語とも目されていますが、配列は存在せず、常にArrayクラスを使います。

 

昔は(といっても1990年代です)、オブジェクトという考え方がなく配列を使った処理を多用していました。

例えば、生徒の成績を管理するにはこんな感じです。

<結果>

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

しかし、現代では1人分のデータは1人分のオブジェクト(より正確にはインスタンス)として表現することが一般的です。

何でも配列に入れていた時代もあった

何でも配列に入れていた時代もあった

 

この点は何度も繰り返しお伝えしていくテーマなので、今は用語に慣れる程度で結構です。

 

<まとめ:隣の人に正しく説明できたらチェックを付けましょう>

□配列は同じ型の複数の変数が並んだものと考えられる
 
□配列の添字(index)は0~(要素数-1)である
 
□拡張for文は、配列の先頭から最後までを連続して処理するときに簡潔に書ける構文である
 
□参照にはハッシュコードが入っている
 

 

まとめができたら、アウトプットとして演習問題にチャレンジしましょう。

 

問題6.配列

 

今回はJavaの配列の作成と使用について見てきました。

次回は、文字と文字列の扱いを学んで、文字列も実は参照型であるということについて学びましょう。

 

【今回の復習Youtube】
 

013-Javaの基本-配列の初期化

014-Javaの基本-配列とfor文

015-Javaの基本-配列のネスト

016-Javaの基本-配列のネストとfor文

 

JavaSE8の解説に戻る

PAGETOP
Copyright © Say Consulting Group, Inc. All Rights Reserved.