Java:繰り返し
1学習の目的
- for と while で同じ処理を繰り返せるようになる。1件の処理が書ければ、100件でも1万件でも処理できるようになる。
- break と continue で流れを制御できるようになる。無限ループを避けるための考え方も身につける。
2基礎解説
| 種類 | 書き方 | 向いている場面 |
|---|---|---|
| for | for (int i = 0; i < n; i++) | 回数が決まっている |
| while | while (条件) | 回数が不明 |
| 拡張for | for (String s : list) | 全要素を処理 |
| do-while | do { … } while (条件); | 最低1回は実行 |
- for は「初期化・条件・更新」の3点セット。for (int i = 0; i < 3; i++) なら「0から始め、3未満の間、1ずつ増やす」——3回繰り返される。
- ⚠ while ではカウンタの更新を忘れない。n++ を書き忘れると条件が永久に変わらず、無限ループでプログラムが止まらなくなる。
- 拡張for(for-each)は全要素を順に処理する。添字を使わないので、範囲を超えるミスが起きない。全件処理ならこちらが安全。
- break はループを抜け、continue はその回だけ飛ばす。「見つかったら終了」なら break、「条件に合わないものは無視」なら continue。
- ループの中で宣言した変数は、ループの外では使えない。合計を求めるなら、変数はループの前に宣言する。
現場使用例:一覧の表示、合計・平均の集計、条件に合うデータの抽出、リトライ処理。
// 基本のfor(3回繰り返す)
for (int i = 1; i <= 3; i++) {
System.out.println(i); // 1, 2, 3
}
// 逆順・2つずつ
for (int i = 10; i >= 1; i -= 3) { … } // 10, 7, 4, 1
// while(回数が決まっていないとき)
int n = 1;
while (n <= 3) {
System.out.println(n);
n++; // ⚠ これを忘れると無限ループ
}
// do-while(条件を満たさなくても1回は実行)
do {
System.out.println("最低1回");
} while (false);
// ⭐ 拡張for(配列やリストの全要素)
String[] items = {"A", "B", "C"};
for (String s : items) {
System.out.println(s);
}
// break と continue
for (int i = 1; i <= 5; i++) {
if (i == 3) continue; // 3だけ飛ばす
if (i == 5) break; // 5で終了
System.out.print(i); // 1, 2, 4
}
// 合計を求める(変数はループの外で宣言)
int[] nums = {10, 20, 30};
int sum = 0; // ← ループの前
for (int v : nums) {
sum += v;
}
System.out.println(sum); // 60
// 二重ループ
for (int i = 1; i <= 2; i++) {
for (int j = 1; j <= 3; j++) { … }
}
3基本ドリル(10問)
出力3行。1 / 2 / 3
for (int i = 1; i <= 3; i++) と書く。
public class Main {
public static void main(String[] args) {
for (int i = 1; i <= 3; i++) {
System.out.println(i);
}
}
}「初期化・条件・更新」の3点セット。i = 1 から始め、i <= 3 の間、i++ で1ずつ増やす。
A. 1回で終わる B. 無限ループになる C. エラーになる D. 何も起きない 選択★☆☆無料
解答 == B
条件が永久に変わらない。
B
プログラムが止まらなくなる。for文なら更新部分が構文に含まれるので、忘れにくい——while を使うときは特に注意する。
出力3行。1 / 2 / 3
変数を前に宣言し、ループの中で n++ する。
public class Main {
public static void main(String[] args) {
int n = 1;
while (n <= 3) {
System.out.println(n);
n++;
}
}
}for と同じ処理を while でも書ける。回数が決まっているなら for、条件次第で回数が変わるなら while が適している。
public class Main {
public static void main(String[] args) {
String[] items = {"A", "B", "C"};
for (String s ____ items) {
System.out.print(s);
}
System.out.println();
}
}出力 == ABC
拡張forで使う区切りの記号。1文字。
:
コロンで「〜の中から順に」を表す。添字を使わないので、範囲外アクセスのミスが起きない。
A. ループを抜ける B. その回だけ飛ばして次へ進む C. 最初から やり直す D. 処理を止める 選択★☆☆無料
解答 == B
break との違いを考える。
B
continue はその回をスキップするだけでループ自体は続く。完全に抜けたいなら break を使う。
出力2行。60 / 20.0
合計用の変数はループの前に宣言する。平均は割るときに小数にする。
public class Main {
public static void main(String[] args) {
int[] nums = {10, 20, 30};
int sum = 0;
for (int v : nums) {
sum += v;
}
System.out.println(sum);
System.out.println(sum / (double) nums.length);
}
}合計用の変数はループの外で宣言する。中で宣言すると毎回0に戻り、正しく集計できない。
public class Main {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
if (i == 3) {
____;
}
System.out.print(i);
}
System.out.println();
}
}出力 == 12
「壊す・中断する」を意味する5文字。
break
break でループを完全に抜ける。3の時点で終了するので、出力は12だけになる。
A. 4回 B. 5回 C. 6回 D. 0回 選択★★☆広告解放
解答 == B
0, 1, 2, 3, 4 の5回。
B
0から始めて「未満」で終わると、回数と一致する。配列の添字が0から始まるため、この書き方が定番になっている。
出力 == 1245
if (i == 3) continue; と書く。print で改行なしに出力する。
public class Main {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue;
}
System.out.print(i);
}
System.out.println();
}
}continue の後の処理は実行されないが、ループ自体は続く。「条件に合わないものだけ除外」したいときに使う。
出力3行
外側は for (int i = 2; i <= 2; i++)、内側は 1〜3。
public class Main {
public static void main(String[] args) {
for (int i = 2; i <= 2; i++) {
for (int j = 1; j <= 3; j++) {
System.out.println(i + "×" + j + "=" + (i * j));
}
}
}
}内側のループが全部回ってから、外側が次に進む。表形式のデータやマス目の処理で使う基本パターン。
4実践シナリオ(5問)
出力3行
添字を使う通常のforなら i+1 が番号になる。
public class Main {
public static void main(String[] args) {
String[] items = {"ノートPC", "マウス", "キーボード"};
for (int i = 0; i < items.length; i++) {
System.out.println((i + 1) + ". " + items[i]);
}
}
}番号が必要なら通常のforを使う。添字は0から始まるので、表示用に i + 1 とする。
出力2行。2件 / 173000円
if で条件を判定し、当てはまるものだけ数える。
public class Main {
public static void main(String[] args) {
int[] prices = {128000, 3200, 45000, 8500};
int count = 0;
int sum = 0;
for (int p : prices) {
if (p >= 10000) {
count++;
sum += p;
}
}
System.out.println(count + "件");
System.out.println(sum + "円");
}
}条件付きの集計はループ + if の組み合わせ。この形が集計処理の基本になる。
出力 == 128000
最初の要素を仮の最大値とし、より大きいものが見つかったら更新する。
public class Main {
public static void main(String[] args) {
int[] prices = {128000, 3200, 45000, 8500};
int max = prices[0];
for (int p : prices) {
if (p > max) {
max = p;
}
}
System.out.println(max);
}
}最初の要素を初期値にするのが安全。もし0を初期値にすると、すべてが負の数の配列で正しく動かない。
出力 == 2番目に見つかりました
equals で比較し、見つかったら break する。
public class Main {
public static void main(String[] args) {
String[] items = {"ノートPC", "マウス", "キーボード"};
String target = "マウス";
for (int i = 0; i < items.length; i++) {
if (items[i].equals(target)) {
System.out.println((i + 1) + "番目に見つかりました");
break;
}
}
}
}見つかった時点で break するのが効率的。1万件の配列でも、2件目で見つかれば残り9998件は調べずに済む。
出力 == 30
奇数のとき continue で飛ばす。2+4+6+8+10 = 30。
public class Main {
public static void main(String[] args) {
int sum = 0;
for (int i = 1; i <= 10; i++) {
if (i % 2 != 0) {
continue;
}
sum += i;
}
System.out.println(sum);
}
}continue で条件外を除外する書き方。if (i % 2 == 0) sum += i; とも書けるが、除外条件が複雑なときは continue のほうが読みやすい。
5仕上げ課題
データ(3つの配列)
String[] names = {"ノートPC", "マウス", "モニター", "キーボード"};
int[] prices = {128000, 3200, 45000, 8500};
int[] counts = {2, 15, 1, 3};
処理
① 各商品の売上(単価 × 数量)を「1. ノートPC:256,000円」の形式で出力
② 売上が5万円以上の商品だけ、末尾に ★ を付ける
③ 全体の合計売上を計算
④ 最も売上の高い商品名を求める
⑤ 平均売上を小数第1位まで表示
期待される出力(7行)
1. ノートPC:256,000円 ★
2. マウス:48,000円
3. モニター:45,000円
4. キーボード:25,500円
---
合計:374,500円(最高:ノートPC)
平均:93,625.0円 総合★★★広告解放
出力7行が完全一致
配列の添字を揃えて使う(names[i]、prices[i]、counts[i])。最大値を求めるには、最大の売上と商品名の両方を記録する変数が必要。平均は合計 ÷ 件数を小数で求め、String.format("%,.1f", 値) で整形する。
public class Main {
public static void main(String[] args) {
String[] names = {"ノートPC", "マウス", "モニター", "キーボード"};
int[] prices = {128000, 3200, 45000, 8500};
int[] counts = {2, 15, 1, 3};
int total = 0;
int maxSales = 0;
String maxName = "";
for (int i = 0; i < names.length; i++) {
int sales = prices[i] * counts[i];
total += sales;
if (sales > maxSales) {
maxSales = sales;
maxName = names[i];
}
String mark = (sales >= 50000) ? " ★" : "";
System.out.println((i + 1) + ". " + names[i] + ":"
+ String.format("%,d", sales) + "円" + mark);
}
double average = total / (double) names.length;
System.out.println("---");
System.out.println("合計:" + String.format("%,d", total)
+ "円(最高:" + maxName + ")");
System.out.println("平均:" + String.format("%,.1f", average) + "円");
}
}1回のループで4つの仕事を同時にこなしている。売上の計算、合計への加算、最大値の更新、そして出力——データを1周する間に必要な処理をまとめるのが効率的な書き方だ。もし合計用に1周、最大値用にもう1周…と分けていたら、4回もデータを読み直すことになる。
3つの配列を添字で対応させている点も重要だ。names[0]・prices[0]・counts[0] が同じ商品を指すという前提でループを回している。この方式は単純だが弱点もあり、配列の長さがずれると破綻する。JV08でクラスを学ぶと、1つの商品を1つのオブジェクトにまとめられるようになり、この危うさが解消される。
最大値の求め方にも注意点がある。maxSales を0で初期化しているが、売上が必ず正の数だと分かっているから成立する。もし損失(マイナス)がありうるデータなら、最初の要素で初期化するべきだ。
平均の計算では (double) のキャストが必須になる。total / names.length はどちらも int なので整数の割り算になり、93625.0 ではなく 93625 になってしまう——JV02で学んだ罠が、ここでも顔を出す。
次章では配列を本格的に学ぶ。今回は簡単に使っただけだが、宣言・初期化・操作を体系的に押さえていく。