配列の後半では、配列の初期値、配列のサイズ確認、多次元配列についての紹介です。配列の概要、記述方法等は前半パートで紹介しています。
もくじ
配列の初期値
配列はnewで実体確保を行った段階でデータ型に応じた初期値が設定されます。例えば、以下のようなプログラムを記述した場合は全て0で初期化されてるため、0が表示されます。
1 2 3 4 |
int[] numbers = new int[5]; for(int i = 0; i < 5; i++){ System.out.println(numbers[i]); } |
以下は配列内に格納される初期値となります。
データ型 | 初期値 |
---|---|
boolean | false |
byte、short、int、long、float、double、char | 0 |
参照型(String等) | null |
参照型とnullの詳細は別途記事にて紹介
配列の要素数を取得する
配列は実体確保および初期化子を記述した時点で要素数が決まります。要素数は「配列名.length」と記述すると配列から要素数を取得することができます。配列の要素数分ループしたい場合などに利用すると、配列の数を変更した際に数値を変更しなくてもよくなり、記述の効率が上がります。
例えば、以下の記述だと配列の要素数を5から7に変更した場合に、2つのループ内で「i < 5」を「i < 7」に変更する必要があります。
1 2 3 4 5 6 7 |
int[] numbers = new int[5]; for(int i = 0; i < 5; i++){ ループ処理1; } for(int i = 0; i < 5; i++){ ループ処理2; } |
配列名.lengthを利用すると、要素数を変更してもループの記述を変更する必要はありません。
1 2 3 4 5 6 7 |
int[] numbers = new int[5]; for(int i = 0; i < numbers.length; i++){ ループ処理1; } for(int i = 0; i < numbers.length; i++){ ループ処理2; } |
多次元配列
多次元配列はイメージとしては配列内に配列を保存して、より多くのデータを効率的に扱うことができます。ただし、配列の入れ子が多いと構造がわかりにくくなったり、処理が重くなったりする場合もあります。
下記のイメージは2次元配列ですが、もっと複雑な配列を扱う3次元、4次元配列もあります。
もちろん通常の配列同様に「宣言」「実体確保」「代入及び参照」という手順を踏んで記述します。
多次元配列の宣言
宣言 | データ型[][] 配列名 ; |
---|---|
記述例 | int[][] numbers ; |
3次元では[][][]となり、4次元配列だと[][][][]となります。
多次元配列の実体確保
実体確保 | 配列名 = new データ型[要素数][要素数] ; |
---|---|
記述例 | numbers = new int[2][5] ; |
多次元配列の全要素数は要素数同士の加算ではなく乗算となりますので、例では「new int[2][5]」となっており全要素数は10となります。
3次元配列だとnew int[3][3][3] ;のように記述します。(全要素数は27)
4次元配列だとnew int[4][4][4][4] ;のように記述します。(全要素数は256)
多次元配列へのデータ代入および参照
データ代入および参照 | 配列名[添え字][添え字] = データ ; 配列名[添え字][添え字] ; |
---|---|
記述例 | numbers[0][4] = 500 ; System.out.println(numbers[0][4]) ; |
「new int[2][5]」の場合、利用できる添え字は以下の組み合わせとなります。
[0][0]、[0][1]、[0][2]、[0][3]、[0][4] [1][0]、[1][1]、[1][2]、[1][3]、[1][4]宣言と実体確保を同時に記述
通常の配列同様に、宣言と実体確保を同時に記述することも可能です。
多次元配列 | データ型[][] 配列名 = new データ型[要素数][要素数] ; |
---|---|
記述例 | int[][] numbers = new int[2][5] ; |
初期化子を利用した多次元配列
初期化子を利用して多次元配列を作成する際には、{}内に{}を入れ子にして記述します。
例えば、以下はnewで2次元配列を作成した記述と初期化子で2次元配列を作成した記述です。
1 2 3 4 5 6 7 8 9 10 |
//new演算子で2次元配列を作成 String[][] colors = new String[3][3]; colors[0][0] = "赤"; colors[0][1] = "紅"; colors[0][1] = "緋"; colors[1][0] = "青"; colors[1][1] = "空"; colors[2][0] = "緑"; //初期化子を利用した2次元配列作成 String[][] new_colors = { {"赤","紅","緋"},{"青","空"},{"緑"} }; |
同じように2次元配列は作成できるのですが、newで作成した場合9つの要素を持つことになります。colorsの[1][2]、[2][1]、[2][2]はデータが代入されていませんが、配列の要素は存在しています。(初期値でnullが代入されている)
初期化子で多次元配列を作成した場合は、配列内の各配列は要素の数をバラバラで作成することができます。上記の初期化子で作成した配列には[1][2]、[2][1]、[2][2]の要素は存在していません。
※実行例はコンパイルから実行までの例を表示しています。
多次元配列の補足
多次元配列を利用する際には、ネストされたループと組み合わせることが多々あります。どのように記述するかは、サンプルプログラムを参照してください。
また、要素数を取得するlengthの扱いにも注意が必要です。以下の2次元配列のイメージをご覧ください。
配列をツリー構造で表した図解です。配列内の要素にアクセスする際は、上の要素から下にたどっていき、記述は左から順序良く並べていくイメージです。例えば、numbers[0][2]には300が代入されています。
多次元配列ではnumbers[0]や[1]の中にさらに配列が入っているイメージなります。「配列名.length」は記述できますが、例えば、上のイメージ図だと要素数は2となります。配列名.lengthでは配列内にある配列の要素数は取得できません。
もし、[0]内にある配列の要素数を確認したい場合は、配列名[0].lengthという記述になります。(イメージ図だと5が取得できる)
2次元配列 サンプルプログラム
以下のプログラムを「Number22.java」という名前でworkフォルダ内に保存します。
保存が完了したら、コマンドプロンプトを起動し、コンパイルおよび実行を行ってみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
class Number22{ public static void main(String[] args){ //new演算子で2次元配列を作成 String[][] colors = new String[3][3]; colors[0][0] = "赤"; colors[0][1] = "紅"; colors[0][1] = "緋"; colors[1][0] = "青"; colors[1][1] = "空"; colors[2][0] = "緑"; //二次元配列を2重ループで扱う for(int i = 0; i < 3; i++){ for(int j = 0; j < 3; j++){ System.out.println(colors[i][j]); } } //初期化子を利用した2次元配列作成 String[][] new_colors = { {"赤","紅","緋"},{"青","空"},{"緑"} }; //二次元配列を2重ループで扱う for(int i = 0; i < new_colors.length; i++){ for(int j = 0; j < new_colors[i].length; j++){ System.out.println(new_colors[i][j]); } } } } |
実行例
C:\work>javac Number22.java
C:\work>java Number22
赤
緋
null
青
空
null
緑
null
null
赤
紅
緋
青
空
緑
Number22のプログラム説明
ループ文が入れ子になっている場合は、①外側のループスタート、②内側のループを行い、③外側のループに戻る、という流れになっています。(詳細は制御文のネスト参照)
—–外側ループ1回目—–外側の変数iは初期値が0になっており、内側のループがスタートします。内側の変数jも0が初期値となっています。最初の表示は「System.out.println(colors[0][0]);」となります。
内側のループは終わるまで続きますので、変数iは0のまま、内側の変数jは1にインクリメントされます。次の表示は「System.out.println(colors[0][1]);」となります。
[i][j]部分のjが増えていき、条件がj < 3となっているので、[0][0]、[0][1]、[0][2]まで表示され内側ループが終了します。—–外側ループ2回目—–
外側のループに戻り、iがインクリメントされて1になります。条件はi < 3となっているので、また内側ループがスタートします。
再度、内側のループがスタートします。内側の変数jは0で初期化されます。表示は「System.out.println(colors[1][0]);」となります。
内側のループは終わるまで続きますので、変数iは1のまま、内側の変数jは1にインクリメントされます。次の表示は「System.out.println(colors[1][1]);」となります。
[i][j]部分のjが増えていき、条件がj < 3となっているので、[1][0]、[1][1]、[1][2]まで表示され内側ループが終了します。—–外側ループ3回目—–
外側のループに戻り、iがインクリメントされて2になります。条件はi < 3となっているので、また内側ループがスタートします。
内側ループは今までと同様、[i][j]部分のjが増えていき、条件がj < 3となっているので、[2][0]、[2][1]、[2][2]まで表示され内側ループが終了します。
外側のループに戻り、iがインクリメントされて3になります。条件はi < 3となっているので、外側ループも終了となります。
下側のループ文では以下のようにforの条件が記述されています。
外側:for(int i = 0; i < new_colors.length; i++){
内側:for(int j = 0; j < new_colors[i].length; j++){
外側のnew_colors.lengthでは、配列直下の要素数を取得できるため2となります。
内側のnew_colors[i].lengthでは、外側のループが回る毎にiがインクリメントされる為、new_colors[0].length(要素数3)、new_colors[1].length(要素数2)、new_colors[2].length(要素数1)となり、配列内部の配列の要素数を取得することが可能です。
配列【後半】 復習問題
- boolean型の配列を作成した場合、配列内部はどのように初期化されるか選んでください。
- 配列の要素数を取得するには○という記述が必要である。○に入る語句を選んでください。
-
1int[][] numbers = new int[5][4] ;
-
1int[][] numbers = new int[5][4] ;
-
1String[][] week = {{"月","Mon"},{"火","Tue"},{"水","Wed"}};
- お疲れ様でした。
-
- 0
- 1
- true
- false
-
- 配列名.lenght()
- 配列名.lenght
- 配列名.length()
- 配列名.length
-
- 20
- 9
- 5
- 4
-
- 5
- 4
- 9
- 20
-
- 月
- 火
- 水
- Wed
まとめ
- 配列は実体確保の段階で内部のデータが初期化される
- 配列名.lengthで配列の要素数を取得できる
- 多次元配列は複雑になるが、たくさんのデータを効率よく管理できる
- 多次元配列はループのネストと組み合わせて利用されることが多い