Java / LESSON 06 / JV06

Java:配列

1学習の目的

2基礎解説

やりたいこと書き方備考
値を並べて作るint[] a = {10, 20, 30};最も簡潔
大きさだけ決めるint[] b = new int[3];初期値が入る
要素数を知るa.lengthカッコは付けない
中身を表示Arrays.toString(a)importが必要
✅ 覚えるべき重要ポイント
  1. 添字は0から始まる。要素が3つなら添字は0・1・2で、最後の要素は a[a.length - 1]a[3] と書くと範囲外エラーになる。
  2. new int[3] は自動的に初期値が入る。数値なら0、booleanなら false、Stringなど参照型なら null。null に対して操作するとエラーになるので注意。
  3. ⭐ 配列を代入しても中身はコピーされないint[] b = a; と書くと同じ配列を2つの名前で指すだけ。片方を変えるともう片方も変わる。
  4. 中身をコピーしたいなら Arrays.copyOf を使う。これなら独立した別の配列になり、一方を変えても他方に影響しない。
  5. 配列の長さは後から変えられない。要素を増やしたいなら作り直すか、可変長のList(JV12)を使う。

現場使用例:商品一覧、点数の集計、月別データ、CSVの1行分。「同じ種類のデータが複数ある」場面はすべて配列の出番

import java.util.Arrays;   // 配列の便利メソッドを使うため

// 宣言のしかた
int[] a = {10, 20, 30};          // 値を並べる
int[] b = new int[3];            // 大きさだけ決める(0が3つ)
String[] s = new String[2];      // null が2つ

// 添字は0から
System.out.println(a[0]);        // 10
System.out.println(a[a.length - 1]);  // 30(最後)
// System.out.println(a[3]);     // ⚠ 範囲外エラー

// 値の変更
a[1] = 99;

// 全要素を処理
for (int v : a) { … }                    // 添字が不要なとき
for (int i = 0; i < a.length; i++) { … } // 添字が必要なとき

// ⭐ 代入は「中身のコピー」ではない
int[] x = {1, 2, 3};
int[] y = x;        // 同じ配列を指すだけ
y[0] = 999;
System.out.println(x[0]);   // 999(元も変わる!)

// 中身をコピーしたいとき
int[] z = Arrays.copyOf(x, x.length);   // 独立した別の配列

// 便利なメソッド
Arrays.toString(a);        // "[10, 99, 30]" 表示用
Arrays.sort(a);            // 小さい順に並べ替え(元を変更)
Arrays.fill(b, 7);         // 全要素を7にする
Arrays.equals(a, b);       // 中身が同じか

// 2次元配列(表形式)
int[][] grid = {{1, 2, 3},
                {4, 5, 6}};
System.out.println(grid[1][2]);    // 6
System.out.println(grid.length);   // 2(行数)
System.out.println(grid[0].length);// 3(列数)

3基本ドリル(10問)

JV06-D01 整数の配列 {10, 20, 30} を作り、最初と最後の要素を出力せよ(2行)。 コーディング★☆☆無料
期待される結果

出力2行。10 / 30

ヒント

最後は a[a.length - 1] で取り出す。

模範解答
public class Main {
    public static void main(String[] args) {
        int[] a = {10, 20, 30};

        System.out.println(a[0]);
        System.out.println(a[a.length - 1]);
    }
}
解説

添字は0から始まるので、最後は length - 1a[a.length] と書くと範囲外エラーになる。

JV06-D02 int[] a = new int[3]; のとき a[0] の値はどれか。
A. null B. 0 C. 未定義 D. エラー
選択★☆☆無料
期待される結果

解答 == B

ヒント

数値型の初期値は何か。

模範解答
B
解説

数値なら0、booleanなら false、String など参照型なら nullが自動的に入る。使う前に必ず値が入っている点はJavaの安全な設計。

JV06-D03 大きさ3の配列を new で作り、初期値を確認せよ(int型・String型の先頭要素を2行で出力)。 コーディング★☆☆無料
期待される結果

出力2行。0 / null

ヒント

new int[3] と new String[3] を作り、[0] を出力する。

模範解答
public class Main {
    public static void main(String[] args) {
        int[] nums = new int[3];
        String[] names = new String[3];

        System.out.println(nums[0]);
        System.out.println(names[0]);
    }
}
解説

String配列の初期値は null。そのまま names[0].length() を呼ぶと NullPointerException になるので、必ず値を入れてから使う。

JV06-D04 配列の要素数を取得するコードを完成させよ。 穴埋め★☆☆無料
コード
public class Main {
    public static void main(String[] args) {
        int[] a = {10, 20, 30};

        System.out.println(a.____);
    }
}
期待される結果

出力 == 3

ヒント

「長さ」を意味する6文字。カッコは付けない。

模範解答
length
解説

配列は length(カッコなし)、文字列は length()(カッコあり)——紛らわしいが区別する必要がある。

JV06-D05 int[] b = a; のあと b[0] = 999; とすると、a[0] はどうなるか。
A. 元のまま B. 999になる C. エラー D. 0になる
選択★☆☆無料
期待される結果

解答 == B

ヒント

配列の代入は中身のコピーではない。

模範解答
B
解説

同じ配列を2つの名前で指しているだけ。片方を変えればもう片方も変わる——意図せずデータを壊す原因になる。

JV06-D06 配列 {30, 10, 20}小さい順に並べ替えて出力せよ(Arrays.sortArrays.toString を使うこと)。 コーディング★★☆広告解放
期待される結果

出力 == [10, 20, 30]

ヒント

import java.util.Arrays; が必要。

模範解答
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] nums = {30, 10, 20};

        Arrays.sort(nums);

        System.out.println(Arrays.toString(nums));
    }
}
解説

Arrays.sort は元の配列を並べ替える(新しい配列を返すのではない)。元の順序を残したいなら、先にコピーを取る。

JV06-D07 配列の中身をコピーするコードを完成させよ。 穴埋め★★☆広告解放
コード
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] a = {1, 2, 3};
        int[] b = Arrays.____(a, a.length);

        b[0] = 999;
        System.out.println(a[0]);
    }
}
期待される結果

出力 == 1

ヒント

「〜のコピー」を意味する6文字のメソッド。

模範解答
copyOf
解説

copyOf なら独立した配列になるので、コピー側を変えても元は 1 のまま。単純な代入との違いがはっきり分かる。

JV06-D08 要素3つの配列で a[3] にアクセスするとどうなるか。
A. null が返る B. 実行時エラー C. コンパイルエラー D. 0が返る
選択★★☆広告解放
期待される結果

解答 == B

ヒント

添字は0・1・2まで。

模範解答
B
解説

ArrayIndexOutOfBoundsException で落ちる。コンパイルは通ってしまうので、実行するまで気づけない——ループの条件を <= と書くミスが典型例。

JV06-D09 2次元配列 {{1,2,3},{4,5,6}} を作り、2行目3列目の値と、行数・列数を出力せよ(3行)。 コーディング★★☆広告解放
期待される結果

出力3行。6 / 2 / 3

ヒント

grid[1][2] が2行目3列目。行数は grid.length、列数は grid[0].length。

模範解答
public class Main {
    public static void main(String[] args) {
        int[][] grid = {{1, 2, 3}, {4, 5, 6}};

        System.out.println(grid[1][2]);
        System.out.println(grid.length);
        System.out.println(grid[0].length);
    }
}
解説

2次元配列は「配列の配列」grid[1] が2行目の配列を指し、そこからさらに [2] で3列目を取り出す。

JV06-D10 大きさ3の配列を作り、全要素を7で埋めて出力せよ(Arrays.fill を使うこと)。 コーディング★★☆広告解放
期待される結果

出力 == [7, 7, 7]

ヒント

Arrays.fill(配列, 値) で一括設定できる。

模範解答
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] a = new int[3];

        Arrays.fill(a, 7);

        System.out.println(Arrays.toString(a));
    }
}
解説

初期値を一括で設定したいときに便利。ループで1つずつ入れるより簡潔に書ける。

4実践シナリオ(5問)

JV06-S01 【点数の集計】配列 {80, 75, 91, 68} の合計・平均(小数第1位)・最高点を出力せよ(3行)。 コーディング★★☆広告解放
期待される結果

出力3行。314 / 78.5 / 91

ヒント

平均は小数にキャストする。String.format("%.1f", 値) で桁を揃える。

模範解答
public class Main {
    public static void main(String[] args) {
        int[] scores = {80, 75, 91, 68};

        int sum = 0;
        int max = scores[0];

        for (int s : scores) {
            sum += s;
            if (s > max) {
                max = s;
            }
        }

        System.out.println(sum);
        System.out.println(String.format("%.1f", sum / (double) scores.length));
        System.out.println(max);
    }
}
解説

1周で合計と最大値の両方を求めている。データを何度も読み直す必要はない。

JV06-S02 【参照の罠を確かめる】配列を単純に代入した場合copyOf でコピーした場合の違いを確認せよ。それぞれ変更後の元の配列の先頭要素を出力すること(2行)。 コーディング★★☆広告解放
期待される結果

出力2行。999 / 1

ヒント

代入した配列を変更すると元も変わる。copyOf なら変わらない。

模範解答
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] a = {1, 2, 3};
        int[] ref = a;
        ref[0] = 999;
        System.out.println(a[0]);

        int[] b = {1, 2, 3};
        int[] copy = Arrays.copyOf(b, b.length);
        copy[0] = 999;
        System.out.println(b[0]);
    }
}
解説

同じ操作でも結果がまったく違う。代入は「別名を付けただけ」、copyOf は「複製を作る」——この違いを知らないと、原因不明のデータ破壊に悩まされる。

JV06-S03 【商品と価格の対応】2つの配列(名前と価格)を添字で対応させ、「ノートPC:128,000円」の形式で3行出力せよ(ノートPC/128000、マウス/3200、モニター/45000)。 コーディング★★☆広告解放
期待される結果

出力3行

ヒント

添字を使う通常のforで、names[i] と prices[i] を同時に使う。

模範解答
public class Main {
    public static void main(String[] args) {
        String[] names = {"ノートPC", "マウス", "モニター"};
        int[] prices = {128000, 3200, 45000};

        for (int i = 0; i < names.length; i++) {
            System.out.println(names[i] + ":"
                    + String.format("%,d", prices[i]) + "円");
        }
    }
}
解説

2つの配列を添字で対応させるのは古典的な手法。ただし配列の長さがずれると破綻するので、JV08で学ぶクラスのほうが安全になる。

JV06-S04 【並べ替えと上位取得】配列 {45000, 128000, 3200, 8500}大きい順に並べ替え、上位2件を出力せよ(2行)。 コーディング★★★広告解放
期待される結果

出力2行。128000 / 45000

ヒント

Arrays.sort で小さい順にしてから、後ろから2つ取り出す。

模範解答
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] prices = {45000, 128000, 3200, 8500};

        Arrays.sort(prices);

        for (int i = prices.length - 1; i >= prices.length - 2; i--) {
            System.out.println(prices[i]);
        }
    }
}
解説

Arrays.sort は小さい順にしかできないので、大きい順に取り出したいなら後ろからループする。逆順のソートには別の方法が必要(JV12で扱う)。

JV06-S05 【2次元配列で表を作る】3人×2科目の点数 {{80,70},{90,85},{60,75}} から、各人の合計を「1人目:150点」の形式で3行出力せよ。 コーディング★★★広告解放
期待される結果

出力3行。150 / 175 / 135

ヒント

外側のループで人、内側のループで科目を回す。

模範解答
public class Main {
    public static void main(String[] args) {
        int[][] scores = {{80, 70}, {90, 85}, {60, 75}};

        for (int i = 0; i < scores.length; i++) {
            int sum = 0;
            for (int j = 0; j < scores[i].length; j++) {
                sum += scores[i][j];
            }
            System.out.println((i + 1) + "人目:" + sum + "点");
        }
    }
}
解説

合計用の変数を内側のループの外・外側のループの中で宣言するのが要点。外に出すと全員分が合算され、内に入れると毎回0に戻る。

5仕上げ課題

JV06-FINAL 【在庫管理レポート】配列を使って、在庫データを集計せよ。

データ
String[] names = {"ノートPC", "マウス", "モニター", "キーボード"};
int[] prices = {128000, 3200, 45000, 8500};
int[] stocks = {5, 42, 0, 18};

処理
① 各商品を「1. ノートPC:128,000円 × 5個 = 640,000円」の形式で出力
 ・在庫0の商品は末尾に ※品切れ を付ける
② 在庫総額(単価×在庫の合計)を計算
在庫がある商品だけの平均在庫数を小数第1位まで表示
④ 在庫金額が最も高い商品名を出力

期待される出力(7行)
1. ノートPC:128,000円 × 5個 = 640,000円
2. マウス:3,200円 × 42個 = 134,400円
3. モニター:45,000円 × 0個 = 0円 ※品切れ
4. キーボード:8,500円 × 18個 = 153,000円
---
在庫総額:927,400円(最高:ノートPC)
平均在庫数:21.7個(在庫あり3件)
総合★★★広告解放
期待される結果

出力7行が完全一致

ヒント

品切れ判定は stocks[i] == 0。平均在庫は在庫0を除いて計算する(5+42+18=65、65÷3=21.666…)。金額は String.format("%,d", 値)、平均は String.format("%.1f", 値) で整形。

模範解答
public class Main {
    public static void main(String[] args) {
        String[] names = {"ノートPC", "マウス", "モニター", "キーボード"};
        int[] prices = {128000, 3200, 45000, 8500};
        int[] stocks = {5, 42, 0, 18};

        int totalValue = 0;
        int maxValue = 0;
        String maxName = "";

        int stockSum = 0;
        int stockCount = 0;

        for (int i = 0; i < names.length; i++) {
            int value = prices[i] * stocks[i];
            totalValue += value;

            if (value > maxValue) {
                maxValue = value;
                maxName = names[i];
            }

            if (stocks[i] > 0) {
                stockSum += stocks[i];
                stockCount++;
            }

            String mark = (stocks[i] == 0) ? " ※品切れ" : "";

            System.out.println((i + 1) + ". " + names[i] + ":"
                    + String.format("%,d", prices[i]) + "円 × "
                    + stocks[i] + "個 = "
                    + String.format("%,d", value) + "円" + mark);
        }

        double avgStock = stockSum / (double) stockCount;

        System.out.println("---");
        System.out.println("在庫総額:" + String.format("%,d", totalValue)
                + "円(最高:" + maxName + ")");
        System.out.println("平均在庫数:" + String.format("%.1f", avgStock)
                + "個(在庫あり" + stockCount + "件)");
    }
}
解説

3つの配列を添字で対応させ、1周で5つの集計を同時に行っている。在庫金額、総額への加算、最大値の更新、在庫数の合計、在庫あり件数——データを1度読むだけで、必要な情報をすべて取り出せる

注目してほしいのは「在庫があるものだけ」の平均だ。単純に 全在庫 ÷ 4 とすると16.25個になるが、品切れの商品を含めた平均に意味はあるだろうか。集計の対象をどう定義するかは、プログラムの問題ではなく業務の問題だ。仕様を決める人と認識を合わせておかないと、正しく動いているのに「求めていた数字と違う」と言われることになる。

そしてこの課題の弱点も見ておきたい。3つの配列が添字で結びついているだけなので、もし誰かが names に1件追加して prices を忘れれば、実行時に範囲外エラーで落ちる。「ノートPCの価格は128000円」という関係が、コード上のどこにも表現されていないのだ。

この危うさを解決するのが、JV08で学ぶクラスだ。商品を1つのオブジェクトとしてまとめれば、名前・価格・在庫が常に一体で動くようになり、ずれようがなくなる。

次章ではメソッドを学ぶ。長くなってきた main の中身を、役割ごとに切り分ける方法を身につける。