Javaプログラミング基礎

講義資料

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

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

配列についての文法的な説明は 教科書の pp.204〜219 を参照してください。

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

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

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

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 文で各要素の値を表示しています。 for 文の 2 番目の式の a.length は 配列 a の要素数を求める書き方です。

いずれの for 文も、a[0], a[1], a[2], ..., a[4] の順に配列 a の要素を処理しています。 この for 文の中身は i を 0 から 1 ずつ増やしていき、 i が 4 になるまで合計 5 回繰り返されます。

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

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

この形が配列の要素を 0 から順に処理する際の標準的な書き方なので、 身につけておく必要があります。

ところで、配列の宣言、初期化の書き方には何種類かあります。 このプログラムの 5,6 行目を 1 つにまとめて、

int[] a = new int[5];

と書くこともできます。 また、宣言と初期化を同時に行い、 5 〜 11 行目をまとめて、

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 番目のプログラムをもう一度見てみましょう。

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 とします。

class SearchMaximum {
    public static void main(String[] args) {
        int[] a = {5, 2, 3};

        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 に最大の値が入っていることになります。