変数を用いますと、データを一つ格納できることはすでに学びました。 たくさんのデータを格納するには、データの個数だけ変数を用意すれば可能です。 しかし、これらのデータを系統的に取り扱うことは困難です。
配列(array)というものを用いますと、たくさんのデータを系統的に格納することができます。 配列とは、データの「入れ物」が並んだものと考えてください。 次の図は、配列のイメージです。
配列には次のような特徴があります。
int
型)の隣に文字列(String
型)を格納したりはできません。
変数を使うためには、変数の宣言が必要でした。
int x;
のように変数を宣言しますと、変数 x
に整数(int
型)が一つ格納できました。
配列を使うためには、配列の宣言と配列の生成という二段階の手続きが必要です。 次のプログラムは、配列を宣言し、生成し、その3番目に整数72を格納し、それを出力するものです。
1: class ArrayTest { 2: public static void main (String[] args) { 3: int[] a; 4: a = new int[10]; 5: a[3] = 72; 6: System.out.println(a[3]); 7: } 8: }
b00a001@Ampere:~/java% java ArrayTest 72 b00a001@Ampere:~/java%
整数(int
型)の場合、配列の宣言は次のように書きます。
int[] arrayname;
ここで、arrayname は配列の変数名です。 配列の生成は、
arrayname = new int[size];
と書きます。 ここで、size は配列の大きさ(「入れ物」の個数)です。 今後、「入れ物」を配列の要素とよぶことにします。
上記のプログラムでは、3行目で変数名が a
である配列を宣言しています。
また、4行目で大きさが10である配列を生成しています。
配列の要素にデータを格納するには、
arrayname[expression] = expression2;
と書きます。
expression 番目の要素に式 expression2 の値を格納します。
ここで、expression は数そのものである必要はありません。
数を値に持つならば、変数や式でもかまいません。
例えば、変数 i
の値が3で x
の値が100ならば、b[i - 1] = x + 1;
によって配列 b
の2番目の要素に101が格納されます。
式
arrayname[expression]
は、配列の expression 番目の要素に格納されたデータを値とします。 なお、配列の何番目の要素かを表すこの式 expression を、配列の添え字(subscript)、またはインデックス(index)とよびます。
上記のプログラムでは、5行目で配列の3番目の要素にデータ72を格納しています。 また、6行目ではそのデータを取り出して出力しています。
上記のプログラムでにおいて、a[10]
は存在しないことに注意してください。
このような、存在しない要素にデータを格納しようとしたり、データを取り出そうとしますと、エラーが発生します。
なお、配列の大きさをどこかに記録しておく必要はありません。 これは、式
arrayname.length
によっていつでも取り出せます。
注意: 教科書によっては、配列の宣言は
int a[];
などと書くと説明しています。
Javaでは、int[] a;
と int a[];
は同じ意味です。
ただし、これらを混在させるのは混乱のもとですので、この授業では前者に統一します。
上記のイメージの通り、配列にデータを格納しましょう。 これは、配列の宣言、配列の生成、配列の要素への代入という手順を踏むとできます。 以下はそのようなプログラムの一部です。
int[] a; a = new int[10]; a[0] = 99; a[1] = 90; a[2] = 81; a[3] = 72; a[4] = 63; a[5] = 54; a[6] = 45; a[7] = 36; a[8] = 27; a[9] = 18;
次のように書きますと、配列の宣言と生成が同時に行えます。
int[] a = new int[10]; a[0] = 99; a[1] = 90; a[2] = 81; a[3] = 72; a[4] = 63; a[5] = 54; a[6] = 45; a[7] = 36; a[8] = 27; a[9] = 18;
さらに、データの格納も同時に行うことができます。 これは次のように書きます。
int[] a = {99, 90, 81, 72, 63, 54, 45, 36, 27, 18};
このことを、配列の初期化とよびます。
配列の初期化では、キーワード new
や配列の大きさは書きません。
配列を処理するときは、for
文による繰り返しがよく用いられます。
次のプログラムは、配列 b
の要素に配列 a
の要素をコピーし、b
の要素を出力した後、その総和を求めるものです。
1: class ArrayIteration { 2: public static void main (String[] args) { 3: int i, sum = 0; 4: int[] a = {99, 90, 81, 72, 63, 54, 45, 36, 27, 18}; 5: int[] b = new int[a.length]; 6: for (i = 0; i < a.length; i++) { 7: b[i] = a[i]; 8: } 9: for (i = 0; i < b.length; i++) { 10: System.out.println("b[" + i + "] is " + b[i]); 11: } 12: for (i = 0; i < b.length; i++) { 13: sum = sum + b[i]; 14: } 15: System.out.println("The sum is " + sum); 16: } 17: }
b00a001@Ampere:~/java% java ArrayIteration b[0] is 99 b[1] is 90 b[2] is 81 b[3] is 72 b[4] is 63 b[5] is 54 b[6] is 45 b[7] is 36 b[8] is 27 b[9] is 18 The sum is 585 b00a001@Ampere:~/java%
5行目で、配列 a
と同じ大きさの配列 b
を宣言し、生成します。
6行目から8行目でコピーが行われます。
式 a.length
の値は10ですので、6行目の for
文では変数 i
は0から9まで動きます。
これは、配列 a
(および配列 b
)の添え字の範囲と一致します。
9行目から11行目で配列 b
の要素を出力します。
12行目から14行目で総和を計算します。
注意: 上記のプログラムで、6行目から8行目までの代わりに
b = a;
と書いても同じ出力が得られます。 ただし、これでは配列の要素はコピーされません。 まったく別の事が行われます。
配列の使用例としまして、成績の集計を行います。 30人のクラスで試験をして、次のような得点データが得られたとします。
95, 80, 65, 0, 85, 100, 79, 85, 93, 0, 88, 90, 80, 98, 75, 95, 58, 85, 88, 70, 75, 82, 100, 60, 92, 55, 0, 95, 83, 81
これを10点きざみで分類し、得点分布を求めるプログラムを考えます。
はじめに、人数を数える配列 counts
を用意します。
得点とこの配列の添え字を次のように対応させます。
得点 | 添え字 |
---|---|
0〜9 | 0 |
10〜19 | 1 |
20〜29 | 2 |
30〜39 | 3 |
40〜49 | 4 |
50〜59 | 5 |
60〜69 | 6 |
70〜79 | 7 |
80〜89 | 8 |
90〜99 | 9 |
100 | 10 |
このように対応させますと、得点 s から添え字を求めるには、式 s/10 で計算できます。 また、添え字 i から得点範囲を求めるには、式 i×10 と i×10+9 で計算できます。
次に、得点を格納する配列 scores
を用意します。
配列の初期化を使って、これに得点を格納します。
このデータをひとつずつ取り出し、得点から添え字を計算し、その分類の人数を1増加させるという操作を繰り返して、得点範囲ごとに人数を数えます。
10行目から12行目で、各分類の人数 counts[i]
をすべて0にします。
13行目から15行目で、各得点 scores[i]
から添え字 scores[i] / 10
を求め、その分類の人数を1増やします。
最後に集計結果を出力します。 17行目で得点範囲を、18行目でその人数を、それぞれ改行せずに出力します。 改行は19行目で行います。
1: class ScoreDistribution { 2: public static void main (String[] args) { 3: int i; 4: int[] counts = new int[11]; 5: int[] scores = { 6: 95, 80, 65, 0, 85, 100, 79, 85, 93, 0, 7: 88, 90, 80, 98, 75, 95, 58, 85, 88, 70, 8: 75, 82, 100, 60, 92, 55, 0, 95, 83, 81 9: }; 10: for (i = 0; i < counts.length; i++) { 11: counts[i] = 0; 12: } 13: for (i = 0; i < scores.length; i++) { 14: counts[scores[i] / 10]++; 15: } 16: for (i = 0; i < counts.length; i++) { 17: System.out.print((i * 10) + " - " + (i * 10 + 9) + " : "); 18: System.out.print(counts[i]); 19: System.out.println(); 20: } 21: } 22: }
b00a001@Ampere:~/java% java ScoreDistribution 0 - 9 : 3 10 - 19 : 0 20 - 29 : 0 30 - 39 : 0 40 - 49 : 0 50 - 59 : 2 60 - 69 : 2 70 - 79 : 4 80 - 89 : 10 90 - 99 : 7 100 - 109 : 2 b00a001@Ampere:~/java%
ある会社のある課には社員が30人います。 社員の年齢の分布を調べることになりました。 10代、20代、30代、40代、50代、60代の6種類に分類し、以下のように棒グラフで表示するプログラムを作成してください。 年齢のデータは次の通りです。
62, 48, 30, 55, 23, 47, 58, 33, 34, 57, 36, 19, 51, 41, 63, 28, 42, 32, 55, 64, 52, 60, 25, 63, 44, 30, 51, 37, 39, 44
このデータをプログラムの中に書き、配列の初期化の要領で配列に格納してください。 なお、10才未満や70才以上の人は、はじめからいないものとしてください。
b00a001@Ampere:~/java% java AgeDistribution 10s * 20s *** 30s ******** 40s ****** 50s ******* 60s ***** b00a001@Ampere:~/java%
今日の演習6にしたがってJavaプログラムを作成し、konishi@twcu.ac.jpあてにメールでそのプログラムを提出してください。 メールには、学生番号、氏名、科目名、授業の日付けを明記してください。