Javaプログラミング基礎 講義資料

配列を用いた大量データの扱い

今まで学んだ知識では、 変数を宣言したぶんのデータの個数しか扱うことができませんでした。 例えば変数を1000個宣言し使うのは非現実的です。 Java で大量のデータを扱うための基本的な機能が「配列 (array) 」です。 配列は同じ種類のデータの集まりに一つの名前をつけ、 ひとまとめにして扱うものです。 そして、一つ一つのデータは番号で指定します。

配列についての文法的な説明は 教科書の pp.206〜219 を参照してください。 (教科書中のプログラムで使われているキーワード double は、 実数 (小数点以下を含む数など) を扱う変数の宣言に使うキーワードです。)

例題: 配列を使って平均を計算する (教科書 p.206 List 9-2とほぼ同一)

3科目の点数から平均点を計算するプログラムを考えます。 点数を入れる変数には、すべて「点数を表す」という共通の目的があります。 配列を使うと、共通の目的の変数を番号をつけてまとめることができます。

このプログラムについて、詳しくは教科書の説明 pp.206-211 を参照してください。

public class Heikin2 {
    public static void main(String[] args) {
        int[] ten;
        int heikin;

        ten = new int[3];
        ten[0] = 63;
        ten[1] = 90;
        ten[2] = 75;
        heikin = (ten[0] + ten[1] + ten[2]) /3;
        System.out.println("平均点は" + heikin + "点");
    }
}

例題: 与えられた数の合計を求める

プログラムの先頭で int 型の配列を用意し、 複数の整数を代入しておきます。 その合計を求めるプログラムを考えてみます。 さらにこのプログラムでは、合計を表示した後、 元の数を改めて表示することにします。

プログラム名は SumAndList とします。

public class SumAndList {
    public static void main(String[] args) {
        int[] a;
        a = new int[5];
        a[0] = 3;
        a[1] = 5;
        a[2] = 6;
        a[3] = 1;
        a[4] = 9;

        int sum = 0;
        for (int i = 0; i < a.length; i++)
            sum = sum + a[i];

        System.out.println("以下の数の合計: " + sum);

        for (int i = 0; i < a.length; i++)
            System.out.print(a[i] + " ");

        System.out.println();
    }
}

2 つの for 文があります。 1 つめの for 文で a の各要素の合計を求め、 2 つめの for 文で各要素の値を表示しています。 a.length は 配列 a の要素数 (今回は5) を求める書き方です。 よって、for 文は i を 0 から 1 ずつ増やしていき、 i が 4 になるまで中身を合計 5 回繰り返します。

いずれの for 文も、変数 i の値は 0,1,2,...,4 と変化します。 その変化に応じて式 a[i] は、 a[0], a[1], a[2], ..., a[4] の順に配列 a の各要素を示すことになります。 よって、1つめの for 文では、

という5つの文を実行しているのと同じことになります。

なお、for 文の形は 2 つとも同じで、次のようになっています。

for (i = 0; i < a.length; i++)
    処理

この形が配列すべての要素に対して、 先頭から順に処理する際の標準的な書き方です。

配列の宣言と初期化

配列の宣言、初期化の書き方には何種類かあります。 このプログラムの冒頭の宣言と初期化を見てみましょう。

int[] a;
a = new int[5];

上の宣言と初期化の2行をまとめて以下のように1つの文で書くこともできます。

int[] a = new int[5];

さらに、以下のような宣言、初期化、代入を同時に行う方法があります。

        int[] a;
        a = new int[5];
        a[0] = 3;
        a[1] = 5;
        a[2] = 6;
        a[3] = 1;
        a[4] = 9;

上の処理は次のように1つの文で書くことができます。

int[] a = new int[]{3, 5, 6, 1, 9};

さらに以下の書き方も同じ意味です。

int[] a = {3, 5, 6, 1, 9};

また、 int[] a;int a[]; は同じ意味ですが、 整数を入れることができる配列という「型」を分かりやすく表わしている int[] a; の書き方がお勧めです。

配列の大きさの制限

配列は、宣言された要素の数を越えて使うことはできません。 また、要素の番号に負の数を使うことはできません。 a[i]i のように、 配列要素の番号を示す整数を「添字 (そえじ) 」または 「インデックス (index) 」と呼びます。 添字は 0 以上、要素数未満である必要があります。

範囲外の配列の要素にアクセスしようとすると、 Java では例外 (Exception) と呼ばれる一種のエラーが発生し、 プログラムが強制的に終了してしまいます。 このようなことを防ぐために、 配列にアクセスする際には、 添字がその配列の範囲内にあるかどうかについて常に気を配る必要があります。

例題: 最大の要素を探す

条件判定の回の例題で、 3 つの値の最大値を求めるプログラム を取り上げました。 この例題の 3 番目のプログラムをもう一度見てみましょう。

public class Max3c {
    public static void main(String[] args) {
        int x = 5;
        int y = 2;
        int z = 3;
        int max;

        max = x;
        if (y > max)
            max = y;
        if (z > max)
            max = z;

        System.out.println("最大値は " + max + " です");

    }
}

このプログラムの考え方を元に、

int[] a = {15, 9, 12, 10, 6, 8, 16, 5, 13, 14};

というような配列があったときに最大の値を探すプログラムを考えます。 (この例では答えは 16 ですが、 任意の組み合わせの数からなる任意の大きさの配列でも きちんと動くプログラムを考えるということです)

元の3つの最大値のプログラムを良く見ると、 最大値の判定のために、 次のような条件判定を yz について 2 回行っています。

if (調べる対象の値 > max)   // もし今回の「調べる対象の値」がこれまでの max を上回るならば
    max = 調べる対象の値;      // max を「調べる対象の値」に更新する

最初に maxx の値とし、 「調べる対象の値」を y, z と進めれば x, y, z のうちの最大の値が maxに求まるというわけです。 では、このようなif文を配列に適用することを考えてみます。

max = a[0];

if (a[1] > max)
    max = a[1];

if (a[2] > max)
    max = a[2];

if (a[3] > max)
    max = a[3];

... if文を配列要素の終わりまで繰り返す

結果として max にすべての要素の中の最大の値が求まる

上のプログラムを見るとif文の繰り返しはfor文を使って 書けば良いことが分かりますね。

max = a[0];

for (int i = 1; i < a.length; i++)
    if (a[i] > max)
        max = a[i];

結果として max にすべての要素の中の最大の値が求まる

以下にプログラムの全体を示します。プログラム名は SearchMaximum とします。

public class SearchMaximum {
    public static void main(String[] args) {
        int[] a = {15, 9, 12, 10, 6, 8, 16, 5, 13, 14};

        int max = a[0];
        for (int i = 1; i < a.length; i++)
            if (a[i] > max)
                max = a[i];

        System.out.println("最大値は" + max + "です");
    }
}

for 文で要素を一つ一つ比較し、 変数 max にそれまでに見つかった最大の値を入れておくようにします。 全ての要素を検査し終わり for 文を抜けると、 変数 max に最大の値が入っていることになります。