Java入門|ループと配列で効率アップ!

配列とループを組み合わせれば、同じ処理を何度も書かずにすっきり進められる

配列は、同じ種類のデータをひとまとめにして扱える便利な仕組みでしたね。けれども、配列の本当の使いやすさがよくわかるのは、繰り返し処理と組み合わせたときです。

たとえば、5人分の点数や7日分の気温、12か月分の売上のように、同じ種類のデータがいくつも並んでいる場合、1つずつ手で処理を書くのは大変です。そんなときに活躍するのが、for文のようなループです。配列の要素は順番に並んでいるので、ループを使えば先頭から最後まで順に処理していくことができます。

ここでは、配列とループを組み合わせるとどのようにコードがすっきりするのか、どんな点に注意すればよいのかを、やさしくていねいに見ていきます。あわせて、配列の大きさを超えてアクセスしてはいけない理由や、入力された数に応じて配列の大きさを決める考え方についても確認していきましょう。

配列とループはとても相性がよい

配列の要素には、添字と呼ばれる番号が順番に付いています。
Javaでは、この添字が 0 から始まり、1、2、3 というように並んでいきます。

この性質があるので、ループを使うと配列の各要素を順番に処理しやすくなります。

たとえば、配列に 5 個の値が入っているなら、

  • 1回目は添字 0
  • 2回目は添字 1
  • 3回目は添字 2
  • 4回目は添字 3
  • 5回目は添字 4

というように、ループ変数を使って自然に順番に取り出せます。

もしループを使わなければ、1つずつ手作業で書くことになります。

System.out.println(data[0]);
System.out.println(data[1]);
System.out.println(data[2]);
System.out.println(data[3]);
System.out.println(data[4]);

この程度ならまだ書けますが、要素数が20個、50個、100個と増えていくと、かなり大変です。
そこで、ループを使うと次のようにすっきり書けます。

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

このように、配列とループを組み合わせると、同じような処理を何度も書かずに済むのです。

なぜコードがすっきりするのか

配列だけでも複数の値をまとめて管理できますが、ループと組み合わせることで、さらに実用的になります。

その理由を表に整理すると、次のようになります。

組み合わせできること
配列だけ同じ型の値をまとめて保存できる
ループだけ同じ処理を繰り返せる
配列 + ループたくさんのデータを順番にまとめて処理できる

つまり、配列はデータを並べて持つ役割、ループはそれを順番に処理する役割を持っています。
この2つがそろうと、データの管理も処理もとても効率的になります。

配列の値を順番に表示するプログラムを見てみよう

まずは、配列とループの基本的な組み合わせを、シンプルな例で見てみましょう。
ここでは、1週間の歩数を配列に入れて、順番に表示するプログラムに変えて説明します。

ファイル名:Sample1.java

class Sample1
{
    public static void main(String[] args)
    {
        int[] steps;
        steps = new int[5];   // 配列を準備する

        steps[0] = 3200;
        steps[1] = 5400;
        steps[2] = 6100;
        steps[3] = 4500;
        steps[4] = 7000;   // 各要素に歩数を代入する

        for(int i = 0; i < 5; i++){
            System.out.println((i + 1) + "日目の歩数は " +
                               steps[i] + " 歩です。");
        }   // ループを使って順番に表示する
    }
}

実行結果

1日目の歩数は 3200 歩です。
2日目の歩数は 5400 歩です。
3日目の歩数は 6100 歩です。
4日目の歩数は 4500 歩です。
5日目の歩数は 7000 歩です。

このプログラムでは、まず steps という配列を作り、5日分の歩数を格納しています。
そのあと for文を使って、配列の先頭から順番に値を取り出して表示しています。

ここで注目したいのは、表示に使っている steps[i] の部分です。
i の値が 0、1、2、3、4 と変わっていくことで、取り出す要素も順番に変わっていきます。

ループの中で添字に変数を使うのがポイント

配列では、添字に数値を直接書くだけでなく、変数を使うことができます。
これがとても重要です。

たとえば Sample1 では、次の部分がポイントでした。

steps[i]

この書き方によって、ループのたびに別の要素を取り出せるようになります。

for文の流れを整理すると、次のようになります。

ループ回数i の値取り出す要素表示される日数
1回目0steps[0]1日目
2回目1steps[1]2日目
3回目2steps[2]3日目
4回目3steps[3]4日目
5回目4steps[4]5日目

ここで、配列の添字は 0 から始まるのに、画面表示は 1日目、2日目 としたいので、表示の部分では i + 1 を使っています。

この違いはとてもよく出てくるので、しっかり意識しておきましょう。

この図は、for文のループ変数 i が 0 から 4 まで変化し、それに合わせて配列の要素を順番に取り出している様子を表しています。

つまり、ループが1回進むごとに、配列の次の要素へ移動しているイメージです。
この仕組みがわかると、配列に入っているたくさんのデータを一括で処理できる理由が見えてきます。

配列の大きさを超えてはいけない

配列を使うときに、とても大事な注意点があります。
それは、用意した要素数を超える添字は使えないということです。

たとえば、5個の要素をもつ配列を作ったとします。

int[] steps;
steps = new int[5];

この場合、使える添字は 0 から 4 までです。

要素数使える添字
50, 1, 2, 3, 4

このとき、次のようなコードは誤りです。

// 誤り
// steps[8] = 9000;

なぜなら、steps[8] という要素は存在しないからです。

配列では、存在しない場所を指定して値を入れたり取り出したりすることはできません。
そのため、ループを書くときにも、何回まで繰り返すのかを正しく考える必要があります。

添字の範囲を間違えないための考え方

添字のミスを防ぐには、次のルールを覚えておくと安心です。

  • 最初の添字は 0
  • 最後の添字は 要素数 - 1

たとえば、要素数が 5 なら最後は 4、要素数が 10 なら最後は 9 です。

この考え方を表にすると、次のようになります。

要素数最後の添字
32
54
87
109

このルールを理解しておけば、for文の条件を書くときにも役立ちます。
たとえば要素数が 5 のとき、

for(int i = 0; i < 5; i++)

と書けば、i は 0 から 4 まで変化します。
これなら配列の範囲を超えません。

添字の注意を図で確認しよう

この図は、配列の中に実際に存在する要素は 0 から 4 までしかないことを示しています。
その外側にある steps[8] のような位置は、そもそも配列の一部ではありません。

このイメージを持っておくと、配列は決められた数の箱を持つ仕組みであり、好きな番号を自由に使えるわけではないことが理解しやすくなります。

要素数があらかじめわからない場合もある

これまでは、配列の要素数を 5 のように固定してきました。
でも、実際のプログラムでは、最初から必要な個数が決まっていないこともあります。

たとえば、次のような場面です。

  • 何人分の身長を入力するか、使う人が決める
  • 何個の買い物金額を登録するか、その場で変わる
  • 何日分の記録を扱うか、入力内容によって変わる

このような場合は、先に個数を入力してもらい、その数に合わせて配列を作ると便利です。

入力された数だけ配列を作るプログラム

ここでは、人数分の身長を入力して表示するプログラムを作成します。
要素数も入力値に応じて決まる形にします。

ファイル名:Sample2.java

import java.io.*;

class Sample2
{
    public static void main(String[] args) throws IOException
    {
        System.out.println("記録する人数を入力してください。");

        BufferedReader br =
            new BufferedReader(new InputStreamReader(System.in));

        String str = br.readLine();
        int num = Integer.parseInt(str);   // 配列の要素数を入力する

        int[] height;
        height = new int[num];   // 入力された人数分だけ配列を準備する

        System.out.println("人数分の身長を入力してください。");

        for(int i = 0; i < num; i++){
            str = br.readLine();   // 1人分ずつ身長を入力する
            int tmp = Integer.parseInt(str);
            height[i] = tmp;   // 入力した身長を配列に保存する
        }

        for(int i = 0; i < num; i++){
            System.out.println((i + 1) + "人目の身長は " +
                               height[i] + " cmです。");   // 保存した身長を表示する
        }
    }
}

実行結果

記録する人数を入力してください。
4
人数分の身長を入力してください。
165
172
158
180
1人目の身長は 165 cmです。
2人目の身長は 172 cmです。
3人目の身長は 158 cmです。
4人目の身長は 180 cmです。

このプログラムの流れを順番に見てみよう

Sample2 の動きは、次のような流れになっています。

順番内容
1何人分のデータを扱うかを入力する
2その人数分の要素をもつ配列を作る
3ループを使って人数分の値を入力する
4もう一度ループを使って全員分を表示する

ここで大切なのは、配列の大きさが num によって決まっていることです。

height = new int[num];

この1行によって、入力された人数にぴったり合った配列が準備されます。
固定の 5 や 10 を使うのではなく、必要な数だけ配列を作れるので、より柔軟なプログラムになります。

ループ条件にも入力された数を使っている

Sample2 では、for文の条件にも num を使っています。

for(int i = 0; i < num; i++)

この書き方にすることで、

  • 入力が 3 なら 3 回
  • 入力が 5 なら 5 回
  • 入力が 10 なら 10 回

というように、配列の大きさに合わせてちょうどよく繰り返せます。

もしここを固定の数値で書いてしまうと、入力人数と合わなくなり、正しく処理できなくなることがあります。
そのため、配列の要素数が変わる場合は、ループ条件にもその値を使うのが基本です。

配列とループを使うと柔軟なプログラムになる

ここまで見てきたように、配列とループを組み合わせると、次のような利点があります。

利点内容
コードが短くなる同じ処理を何度も書かなくてよい
修正しやすい要素数が変わっても対応しやすい
ミスを減らせる手作業で同じ文を書く量が減る
柔軟に対応できる入力された個数に応じて処理を変えられる

特に、入力された個数に応じて配列を作るやり方は、実際のプログラムでもとてもよく使われる考え方です。

配列とループの組み合わせで意識したいこと

最後に、この内容で特に意識しておきたいポイントを整理しておきましょう。

ポイント内容
配列の添字0 から始まる
ループ変数添字として使える
配列の範囲要素数を超える添字は使えない
要素数が不明な場合先に入力させてから配列を作る
ループ条件配列の大きさに合わせて書く

このあたりがしっかり理解できると、配列をただ保存のために使うだけでなく、実際に活用できるようになってきます。

配列はループと一緒に使うと力を発揮する

配列は、複数の値をまとめて扱うための仕組みです。そしてループは、同じ処理を繰り返すための仕組みです。
この2つを組み合わせることで、たくさんのデータを順番に、しかも効率よく処理できるようになります。

最初は、添字が 0 から始まることや、配列の範囲を超えてはいけないことに少し戸惑うかもしれません。けれども、配列の並びとループの流れをセットで考えるようになると、とても自然に理解できるようになります。

これから先、配列の値を集計したり、平均を出したり、条件に合うデータを探したりするときにも、今回学んだ「配列とループの組み合わせ」は何度も登場します。ここでしっかり土台を固めておくと、Javaのプログラムがどんどん書きやすくなります。