Java入門 STEP8|配列を使ってみよう

karin@taishi@felmia

配列とは?

ここまで、値を保存するときには変数を使ってきました。

例えば、3人分の点数を保存する場合、それぞれ変数を作ることができます。

int score1 = 80;
int score2 = 65;
int score3 = 90;

3人程度なら、この書き方でもそれほど困らないかもしれません。

しかし、100人分の点数を保存するとしたらどうでしょうか。

score1score2score3……と100個の変数を作るのは大変です。

Javaでは、このような同じデータ型の複数の値をまとめて扱うために「配列」を使うことができます。

例えば、先ほどの3人分の点数は、配列を使うと次のようにまとめられます。

int[] scores = {80, 65, 90};

これで、scoresという1つの配列の中に、3つのint型の値を保存できます。

配列のイメージ

配列の中では、複数の値が順番に並んでいます。

添字(index)012
806590

それぞれの値には、値が入っている場所を表す番号があります。

この番号を「添字(インデックス)」と呼びます。

ここで、とても重要なポイントがあります。

⚠ 配列の添字は「0」から始まる

3つの値が入っている配列の場合、

1つ目 → scores[0]
2つ目 → scores[1]
3つ目 → scores[2]

となります。

1つ目だから[1]ではありません。

配列を初めて使うときに、とても間違えやすいポイントなので覚えておきましょう。

配列から値を取り出してみよう

先ほどの配列から最初の点数を取り出す場合は、

scores[0]

と書きます。

例えば、

System.out.println(scores[0]);

とすると、

実行結果

80

と表示されます。

同じように、

scores[1] → 65
scores[2] → 90

となります。

ルミィ
ルミィ

配列は「番号の付いた箱が横に並んでいる」と考えると分かりやすいよ♪
ただし、最初の箱の番号は「0」からスタート!

配列を作って値を取り出してみよう

それでは、実際に配列を使ってみましょう。

今回は新しくArraySampleクラスを作成してください。

作成できたら、次のコードを入力して実行してみましょう。

public class ArraySample {

    public static void main(String[] args) {
        int[] scores = {80, 65, 90};

        System.out.println(scores[0]);
        System.out.println(scores[1]);
        System.out.println(scores[2]);
    }

}

実行結果

80
65
90

scoresという配列には、806590の3つの値が順番に入っています。

そして、

scores[0] → 1つ目の値
scores[1] → 2つ目の値
scores[2] → 3つ目の値

を取り出しています。

配列の書き方を確認しよう

今回使った、

int[] scores = {80, 65, 90};

を分けて見てみましょう。

部分意味
int配列に入れるデータ型
[]配列であることを表す
scores配列の名前
{80, 65, 90}配列に入れる値

int[]と書くことで、「int型の値を複数入れられる配列」を作っています。

文字列をまとめたい場合は、String[]を使うこともできます。

String[] names = {"Lumy", "Java", "Eclipse"};

この場合も添字は0から始まるため、

names[0] → Lumy
names[1] → Java
names[2] → Eclipse

となります。

配列の値を変更してみよう

配列に入っている値は、あとから変更することもできます。

例えば、

scores[1] = 75;

と書くと、2つ目の値を65から75に変更できます。

先ほど作ったArraySampleクラスを、次のように変更してみましょう。

public class ArraySample {

    public static void main(String[] args) {
        int[] scores = {80, 65, 90};

        scores[1] = 75;

        System.out.println(scores[0]);
        System.out.println(scores[1]);
        System.out.println(scores[2]);
    }

}

実行結果

80
75
90

ここでも重要なのは、scores[1]2つ目の値を表していることです。

配列では「何番目」と「添字」が1つずれる

1つ目 → [0]
2つ目 → [1]
3つ目 → [2]

例えば「2つ目の値を変更したい」ときは、scores[2]ではなくscores[1]を指定します。

配列の要素数を調べてみよう

配列に入っている値の数を調べたいときは、lengthを使います。

例えば、次の配列には3つの値が入っています。

int[] scores = {80, 65, 90};

この配列の要素数は、

scores.length

で取得できます。

実際にlengthを使ってみよう

新しくArrayLengthSampleクラスを作成してください。

public class ArrayLengthSample {

    public static void main(String[] args) {
        int[] scores = {80, 65, 90};

        System.out.println(scores.length);
    }

}

実行結果

3

scoresには3つの値が入っているため、scores.lengthの結果は3になります。

添字とlengthを混同しないようにしよう

3つの値が入っている配列の場合、

要素数 → 3
最後の添字 → 2

です。

添字は0から始まるため、要素数と最後の添字は同じ数字にはなりません。

配列にない場所を指定するとどうなる?

配列を使うときは、指定する添字が配列の範囲を超えないように注意する必要があります。

例えば、次の配列には3つの値が入っています。

int[] scores = {80, 65, 90};

要素数は3ですが、添字は0から始まるため、使用できるのは、

scores[0]
scores[1]
scores[2]

までです。

では、次のように書くとどうなるでしょうか。

System.out.println(scores[3]);

scores[3]は4つ目の値を表します。

しかし、この配列には3つしか値がないため、存在しない場所を指定していることになります。

このコードを実行すると、エラーが発生します。

⚠ 配列の範囲を超えないようにしよう

要素数が3の場合、

使える添字 → 0 1 2

使えない添字 → 3以上

となります。

配列の要素数が3だからといって、scores[3]まで使えるわけではありません。

「要素数が3なら、最後の添字は2」という点に注意しましょう。

エラーメッセージも確認してみよう

配列の範囲外を指定すると、実行時に次のようなエラーが表示されます。

ArrayIndexOutOfBoundsException

これは、配列の範囲を超えた添字を指定したときに発生するエラーです。

今後このエラーを見かけたら、まず配列の添字が正しい範囲になっているか確認してみましょう。

ルミィ
ルミィ

配列の要素数が3なら、最後は[3]じゃなくて[2]だよ!
「添字は0から」を思い出してね♪

配列とfor文を組み合わせてみよう

配列は、STEP6で学んだfor文と組み合わせることで、さらに便利に使えます。

例えば、配列に入っているすべての点数を順番に表示してみましょう。

新しくArrayLoopSampleクラスを作成してください。

public class ArrayLoopSample {

    public static void main(String[] args) {
        int[] scores = {80, 65, 90};

        for (int i = 0; i < scores.length; i++) {
            System.out.println(scores[i]);
        }
    }

}

実行結果

80
65
90

今回のfor文では、

int i = 0

で、添字と同じ0からスタートしています。

そして、

i < scores.length

で、iが配列の要素数より小さい間、処理を繰り返しています。

処理の中にある、

scores[i]

iは、繰り返すたびに変化します。

iの値scores[i]取り出される値
0scores[0]80
1scores[1]65
2scores[2]90
3条件がfalseになり終了

iが3になると、

3 < scores.length

つまり、

3 < 3

falseになるため、繰り返しが終了します。

なぜ「i < 3」と書かないの?

今回の配列は3つの値なので、

i < 3

と書いても同じ結果になります。

しかし、あとから配列を、

int[] scores = {80, 65, 90, 70, 100};

のように5つへ増やした場合、i < 3のままでは最初の3つしか処理できません。

一方、

i < scores.length

としておけば、scores.lengthは自動的に5になります。

そのため、配列の要素数が変わってもfor文の条件を書き換える必要がありません。

配列をfor文で処理するときはlengthを活用しよう

i < 3のように要素数を直接書くより、

i < scores.length

と書いておけば、配列の要素数が変わっても対応できます。

「あとからデータが増減しても、できるだけ修正する場所を減らす」という考え方は、STEP7で学んだメソッドと同じように、プログラムを作るうえで大切です。

ルミィ
ルミィ

STEP6のfor文と配列がつながったね♪
iを添字として使えば、配列の中身を0番から順番に取り出せるよ!

拡張for文を使ってみよう

先ほどは、for文とlengthを使って配列の中身を順番に取り出しました。

for (int i = 0; i < scores.length; i++) {
    System.out.println(scores[i]);
}

Javaには、配列の中にある値を最初から最後まで順番に取り出したい場合に、より簡単に書ける方法があります。

これを「拡張for文」と呼びます。

拡張for文の書き方

基本的な形は次のようになります。

for (データ型 変数名 : 配列) {
    繰り返したい処理
}

例えば、scoresの値を順番に取り出す場合は次のように書きます。

for (int score : scores) {
    System.out.println(score);
}

scoresから値が1つずつ取り出され、その値がscoreに入ります。

そのため、自分でiを増やしたり、scores[i]と書いたりする必要がありません。

実際に拡張for文を使ってみよう

新しくEnhancedForSampleクラスを作成してください。

public class EnhancedForSample {

    public static void main(String[] args) {
        int[] scores = {80, 65, 90};

        for (int score : scores) {
            System.out.println(score);
        }
    }

}

実行結果

80
65
90

処理の流れを見てみましょう。

繰り返しscoreに入る値
1回目80
2回目65
3回目90

scoresに入っている値が、先頭から順番にscoreへ入ります。

すべての値を取り出したら、繰り返しは終了します。

通常のfor文とどう使い分ける?

どちらも配列を順番に処理できますが、違いがあります。

通常のfor文拡張for文
添字iを使える添字を使わない
特定の位置を意識した処理がしやすい全要素を順番に処理しやすい
書く内容が少し多い短く書きやすい

例えば、単純にすべての点数を表示したいだけなら、拡張for文はとても分かりやすい書き方です。

一方、

「何番目のデータなのかも使いたい」

「特定の添字の値を操作したい」

といった場合は、通常のfor文の方が扱いやすいことがあります。

全部の値を順番に使うなら拡張for文も便利

通常のfor文

for (int i = 0; i < scores.length; i++)

添字を使いながら繰り返す

拡張for文

for (int score : scores)

配列の値を1つずつ取り出して繰り返す

まずは、この違いを覚えておけば大丈夫です。

ルミィ
ルミィ

i[ ]が出てこないから、全部の値を順番に見るだけならスッキリ書けるね♪

配列を使って合計を求めてみよう

配列と繰り返し処理を組み合わせると、配列に入っている値を使って計算することもできます。

例えば、次の3人分の点数の合計を求めてみましょう。

806590

もちろん、

80 + 65 + 90

と直接書くこともできます。

しかし、人数が増えるたびに計算式を書き換えるのは大変です。

そこで、配列と拡張for文を使って合計を計算してみましょう。

実際に合計を計算してみよう

新しくArrayTotalSampleクラスを作成してください。

public class ArrayTotalSample {

    public static void main(String[] args) {
        int[] scores = {80, 65, 90};
        int total = 0;

        for (int score : scores) {
            total += score;
        }

        System.out.println("合計:" + total);
    }

}

実行結果

合計:235

最初に、

int total = 0;

として、合計を入れるための変数を用意しています。

そして、拡張for文でscoresの値を1つずつscoreに取り出します。

total += score;

は、STEP3で学んだ複合代入演算子です。

これは、

total = total + score;

と同じ意味になります。

処理の流れを見てみましょう。

取り出したscore計算total
800 + 8080
6580 + 65145
90145 + 90235

繰り返すたびにtotalへ点数が加算され、最後にはすべての点数の合計が入ります。

平均も求めてみよう

合計が分かれば、配列の要素数で割ることで平均を求めることができます。

先ほどのコードに、平均を求める処理を追加してみましょう。

新しくArrayAverageSampleクラスを作成してください。

public class ArrayAverageSample {

    public static void main(String[] args) {
        int[] scores = {80, 65, 90};
        int total = 0;

        for (int score : scores) {
            total += score;
        }

        double average = (double) total / scores.length;

        System.out.println("合計:" + total);
        System.out.println("平均:" + average);
    }

}

実行結果

合計:235
平均:78.33333333333333

ここでは、

(double) total

と、STEP2で学んだキャストを使っています。

totalint型ですが、double型へキャストしてからscores.lengthで割ることで、小数部分を含んだ平均を求めることができます。

今回の場合、

235 ÷ 3

なので、平均は約78.33です。

もしキャストせずに、

double average = total / scores.length;

とすると、int同士で先に割り算が行われます。

そのため、

235 ÷ 3 → 78

となってからdouble型へ代入され、結果は78.0になります。

平均など、小数部分も必要な計算ではデータ型に注意しよう

double average = (double) total / scores.length;

totaldouble型へキャストしてから割り算することで、小数部分を含んだ結果を求めることができます。

STEP2で学んだ型変換が、実際の計算でも使われています。

ルミィ
ルミィ

STEP2で出てきたキャストがここで使えるね♪
平均みたいに小数まで求めたいときは、計算しているデータ型にも注目しよう!

よくある間違い

配列では、特に添字が0から始まることによる間違いが起こりやすくなります。

うまく動かないときは、次のポイントを確認してみましょう。

1つ目の値を[1]で指定してしまう

配列の添字は0から始まります。

例えば、

int[] scores = {80, 65, 90};

の場合、

scores[0] → 80
scores[1] → 65
scores[2] → 90

となります。

「何番目」と「添字」は同じではない

1つ目 → [0]
2つ目 → [1]
3つ目 → [2]

「1つ目だからscores[1]」と考えないように注意しましょう。

lengthを最後の添字だと思ってしまう

scores.lengthは、最後の添字ではなく配列に入っている要素の数を表します。

3つの値が入っている場合、

scores.length → 3

最後の添字 → 2

となります。

そのため、

scores[scores.length]

となります。

最後の添字は「length – 1」

要素数が3 → 最後の添字は2
要素数が5 → 最後の添字は4
要素数が10 → 最後の添字は9

添字が0から始まるため、最後の添字は要素数より1小さくなります。

配列の範囲を超えてしまう

存在しない添字を指定すると、先ほど学んだArrayIndexOutOfBoundsExceptionが発生します。

このエラーが表示された場合は、

「指定した添字が0以上になっているか」

「指定した添字が配列の要素数より小さいか」

を確認してみましょう。

for文の条件を「<=」にしてしまう

配列とfor文を組み合わせる場合にも注意が必要です。

次の条件は間違いです。

for (int i = 0; i <= scores.length; i++) {
    System.out.println(scores[i]);
}

scores.lengthが3の場合、iが3のときも条件がtrueになります。

すると、

scores[3]

を取り出そうとして、配列の範囲を超えてしまいます。

正しくは、

for (int i = 0; i < scores.length; i++) {
    System.out.println(scores[i]);
}

です。

配列をfor文で繰り返すときは条件に注意

基本的な形は、

i = 0

i < 配列.length

i++

です。

i <= 配列.lengthにすると、最後に配列の範囲を1つ超えてしまいます。

配列に違うデータ型の値を入れようとする

配列には、宣言したデータ型に合った値を入れます。

例えば、

int[] scores

int型の配列です。

そのため、点数などの整数を入れることができますが、"Lumy"のような文字列を入れることはできません。

ルミィ
ルミィ

配列で困ったら、まず「添字は0から」「最後はlength – 1」を確認してみよう♪
for文ならi < 配列.lengthもチェックだね!

STEP8のまとめ

このSTEPでは、複数の値をまとめて扱うことができる「配列」について学びました。

最後に、今回のポイントを振り返っておきましょう。

  • 配列を使うと、同じデータ型の複数の値をまとめて管理できる
  • int[]String[]のように、データ型のあとに[]を付けて配列を作る
  • 配列の値は、scores[0]のように添字を指定して取り出す
  • 配列の添字は0から始まる
  • 配列に入っている値は、あとから変更することもできる
  • lengthを使うと、配列の要素数を取得できる
  • 最後の添字はlength - 1になる
  • 配列の範囲を超えた添字を指定すると、ArrayIndexOutOfBoundsExceptionが発生する
  • for文と配列を組み合わせると、配列の値を順番に処理できる
  • 拡張for文を使うと、配列のすべての値を簡単に順番に取り出せる
  • 配列と繰り返し処理を組み合わせることで、合計や平均なども求められる
  • 平均を小数まで求める場合は、キャストを使って計算するデータ型にも注意する

配列を使えるようになると、たくさんのデータを1つずつ別の変数に入れるのではなく、まとめて管理できるようになります。

そして、配列は単独で使うだけでなく、for文などの繰り返し処理と組み合わせることで、さらに便利になります。

今後Javaを学んでいく中でも、「複数のデータをまとめて、順番に処理する」という考え方は何度も登場します。

ルミィ
ルミィ

STEP8クリア!
配列とfor文を組み合わせると、たくさんのデータもまとめて処理できるね♪
「添字は0から」は忘れないでね!

次のSTEPへ

ここまでは、変数や配列、メソッドなどを使って、データを扱ったり処理をまとめたりする方法を学んできました。

では、名前や点数などの関連するデータと、そのデータを使う処理を1つにまとめて扱いたい場合はどうすればよいでしょうか?

次のSTEPからは、Javaを学ぶうえで重要なオブジェクト指向について少しずつ学んでいきます。

まずは、その基本となる「クラス」と「オブジェクト」から見ていきましょう。

STEP9「クラスとオブジェクトを使ってみよう」

記事URLをコピーしました