こんにちは。ECF Techブログ
担当 Michiharu.Tです。
Javaプログラミング入門記事の第5章をお送りいたします。
第5章のテーマは「配列」です。
第5章も2回のパートに分けて掲載します。今回はPart1です。
本連載の初回および章立ての一覧については下記のリンクから確認できます。
解説動画
2023/12/22 解説動画を掲載しました。
5-1 配列の基本
配列はデータ構造の1つです。「各生徒の得点」のような、複数の類似する値をまとめて取り扱う用途に適しています。
下に配列のイメージを示します。
- 変数名:配列は複数の入れ物を1つの変数名で管理します。
- 添字:入れ物1つ1つにつけられた番号です。添字は0から始まります。
- 要素:配列の各入れ物のことです。
1つの変数名でそれぞれの入れ物を扱えるように、添字がつけられています。「配列arrayの(0から数えて)1番目の要素に入っている値を取得する」などの言い方をします。上の図だと6
を取り出すことになります。
5-1-1 配列の利用
実際に配列を使用するためのプログラムについて説明します。配列の利用は、下の3つの手順で行います。
- 変数の宣言
- 配列の生成と代入
- 各要素の利用
下のプログラムを例にそれぞれの手順を説明します。
プログラム例
public class Main{ public static void main(String[] args){ //変数の宣言 int[] array; //配列の生成と代入 array = new int[5]; //2番目の要素に5を代入 array[2] = 5; //要素の値を表示 System.out.println(array[2]); } }
実行結果
5
(1)変数の宣言
始めに行なうのが変数の宣言です。配列を扱う変数を宣言するための文法は次のようになります。
型名[] 変数名;
プログラム例では次のようになっています。
int[] array;
下にイメージを示します。
(2)配列の生成と代入
次に配列の生成と代入です。配列を準備し、変数で扱えるようにする処理となります。文法を示します。
変数名 = new 型名[要素数];
- 型名は、変数の型と一致させる必要があります。
- 要素数は、配列として用意する入れ物の数です。
要素数は、配列として用意する入れ物の数です。プログラム例では次のようになっています。
array = new int[5];
下にイメージを示します。
この時変数arrayに代入されるのは、図に示すとおり、生成した配列の位置情報です。詳しくは5-4でお伝えします。一旦は「この代入操作をしておけば、変数で配列が扱える」という理解でOKです。
手順の(1)と(2)は1つの文で記述することもできます。その場合は下のような文法となります。
型名[] 変数名 = new 型[要素数];
プログラム例で示すと次のようになります。
int[] array = new int[5];
(3)各要素の利用
配列を利用する準備ができました。各要素を利用する際は次のように記述します。
変数名[添字]
プログラム例では次のようになっています。
array[2] = 5; //2番目の要素に5を代入 System.out.println(array[2]); //要素の値を表示
下にイメージを示します。
5-1-2 配列のための便利な文法
配列の生成や操作のための便利な文法をご紹介します。
配列の初期化
下の記述は、配列の生成と同時に各要素に値を設定することができます。
型名[] 変数名 = {値,値,値,...};
配列の要素数を取得
下の記述は、配列の要素数を取得することができます。
変数名.length
上記2つの文法を活用したプログラム例を示します。
プログラム例
public class Main{ public static void main(String[] args){ //配列の準備 int[] array = {11,12,13,14,15}; //配列の内容を表示 System.out.println(array[2]); System.out.println(array[4]); //配列の要素数を表示 System.out.println(array.length); } }
実行結果
13 15 5
解説
- 4行目で要素数5つの配列を生成し、同時に値を設定しています。
- 9行目は
array.length
の表記を使い、配列arrayの要素数を表示しています。
5-2 配列とfor文
for文を使うことで、配列を効率的に処理することができます。始めにプログラム例を示します。
プログラム例
public class Main { public static void main(String[] args) { int[] array = {2,4,6,8,10}; //iが0~4まで1ずつ増加しながらくり返し for(int i = 0; i < array.length; i++) { //各要素を表示 System.out.println(array[i]); } } }
実行結果
2 4 6 8 10
解説
- for文の継続条件に
i < array.length;
と記述することで、くり返し回数を配列の要素数と合わせることができます。 array[i]
と記述することで、下図のように配列の各要素を順に示すことができます。
i < 5
と記述することもできますが、配列の要素数が後から変更になった場合に修正が必要となってしまいます。i < array.length
とすることで、仮に配列の要素数が変更になったとしても修正をしなくて済むようにしています。5-3 配列と実行時エラー
Javaのようなコンパイラを使用するプログラム言語では、エラーが発生するタイミングに基づく、下の2つのエラーがあります。
- コンパイルエラー:コンパイル時に発生するエラー
- 実行時エラー:コンパイルは成功するが、実行時に発生するエラー
配列を扱う際には、実行時エラーも発生しやすいので注意が必要です。下のプログラムを例に説明します。
プログラム例
public class Main { public static void main(String[] args) { int[] array = {2,4,6,8,10}; System.out.println(array[5]); } }
実行結果
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5 at Main.main(Main.java:4)
解説
実行結果には見慣れない英文が表示されています。これが実行時エラーです。
このプログラムでは5つの要素を持つ配列を生成し、変数arrayで扱えるようにしています。要素数は5なので、添字として使える範囲は0〜4となります。ですが、4行目ではarray[5]
の記述により、範囲外の添字を使っているためエラーとなっています(下図)。
実行時エラーが発生すると、プログラムは基本的に強制終了することになります。
Main.java:4
という記述があり、Main.javaの4行目で発生していることがわかります。5-4 参照型変数
配列を扱う変数は参照型変数と呼ばれるタイプの変数です。本節では参照型変数について学びます。
5-4-1 基本データ型と参照型
2章でJavaの型には、基本データ型と参照型の2種類があるとお伝えしました。基本データ型はlong
,int
,short
,byte
,double
,float
,char
,boolean
の8種類だけです。一方、配列を扱う変数や文字列を扱うString型などは参照型となります。
本章で学習している配列を扱う変数は型部分を型名[]
のように記述します。型名の部分にはint[]
のように基本データ型も使えますが、[]
がつく場合は配列を扱う参照型となります。
5-4-2 メモリとアドレス
参照型の性質を説明するにあたり、まず始めにメモリとアドレスについて簡単にお伝えいたします。メモリはコンピュータを構成する部品の1つで、一時的に情報を記録できる部品です。下図のように、任意の情報が入れられる入れ物がたくさん並んでいるイメージです。
この入れ物1つ1つにはアドレスと呼ばれる位置情報が割り振られており、参照型変数はこのアドレスを代入するタイプの変数となります。
5-4-3 基本データ型との違い
では、アドレスを代入する参照型の変数は、基本データ型の変数とどう違うのでしょうか?まずは2つの違いを下図に示します。左はそれぞれの変数を使ったプログラム例、右にはイメージを示しています。
基本データ型の場合は変数が準備され、その変数に直接値が入っています。
それに対し、配列(参照型)の場合は次の手順で変数が用いられています。
- 参照型変数を宣言する。(
int[] array;
) - 配列に必要な領域をメモリ内に確保し、そのアドレスを参照型変数に代入する。(
array = new int[5];
) - 参照型変数が示す領域に値を代入する。(
array[3] = 8;
)
つまり、参照型変数に代入されているのは値の入れ物を指し示すための位置情報です。
なぜ、このような複雑なしくみになっているのか?という点については、学習を進める上で徐々に理解できますので一旦ここでは割愛します。現時点では、次節に示す動作の特徴を理解できていれば問題ありません。
5-4-4 参照型変数の動き
参照型変数の動作について確認します。始めにプログラム例を示します。
プログラム例
public class Main { public static void main(String[] args) { int[] array = {5,6,7,8,9}; int[] refer = array; refer[3] = 15; System.out.println(array[3]); } }
実行結果
15
解説
始めにint[] array = {5,6,7,8,9};
で配列が用意され、同時に値が設定されます。イメージを示します。
arrayの四角内の●はアドレスが入っていると考えてください。変数arrayにはアドレスが入っているので、メモリに確保された配列の入れ物を指し示しています。
次にint[] refer = array;
で、変数arrayの内容を新たに宣言した変数referに代入しています。この時、変数referに代入されるのは変数arrayに代入されているアドレスです。したがって、下図のように変数referは変数arrayと同じ配列を指し示します。
次のrefer[3] = 15;
で、変数referが指し示す配列の3番目に15
を代入しています。下図のようになります。
最後にarray[3]
の値を表示しています。先程変数referを使って代入した15
を指すことになりますので、15
が表示されます。
ポイントはint[] refer = array;
で代入されるのは、配列そのものではなくあくまでアドレスであるという点です。