Javaの基礎知識(基礎編)

【Javaの基礎知識】for, while, do-while の違いと使い分け|無限ループを防ぐ実践例

Javaのプログラムでは、同じ処理を繰り返すことが多く、繰り返し処理(ループ構文)の理解は不可欠です。本記事では、for、while、do-while の使い方を徹底解説し、具体的なサンプルコードを交えてわかりやすく説明します。

Javaループ処理の基礎理解

Javaで同じ処理を繰り返し実行するために重要なのがループ処理です。ループ処理を理解することで、記述量を減らし保守性を高めたコードを書くことができるようになります。

さらに、実行する処理の内容によって適切なループ構文を使い分けることで、無限ループを防ぎながら効率的にプログラムを動作させることが可能です。

このセクションでは、Javaにおけるループ処理の基本について学んでいきます。

ループ処理とは何か

ループ処理とは、同じ処理を条件が満たされている間繰り返し実行する仕組みのことを指します。

繰り返し処理はJavaのプログラムの中で多く使われており、ループ構文を使うことで記述量を減らし、処理を整理することができます。

ループ処理でプログラムが効率化する理由

ループ処理を使用することで同じ処理を何度も記述する必要がなくなり、ソースコードが短くなります。

繰り返し処理が必要な場合にループ処理を使わずに対応しようとすると、同じ内容の処理を何度も書くことになり、変更があった場合にはすべて修正する必要が出てきます。

ループを使えば、処理を1箇所にまとめることができるため、保守性を高めながら効率良くコードを記述することができます。

同じ処理を繰り返す必要性と活用例

ループ処理が必要になる場面として、配列やリストの中身を順番に処理する場合や、ユーザーからの正しい入力が得られるまで繰り返し入力を受け付ける場合などがあります。

また、特定の条件を満たすまで処理を繰り返すときにもループ処理は欠かせません。

このように繰り返しの必要性は多くのプログラムに存在し、ループ処理を活用することで処理をシンプルかつ柔軟に記述できるようになります。

ループ制御を学ぶ break と continue の使い方

ループ処理を使いこなすにはbreakとcontinueの使い方を理解することが重要です。

breakはループ処理を強制的に終了させるために使用し、continueはループ内の残りの処理をスキップして次のループ処理へ移行します。

これらを正しく使うことで処理効率を向上させつつ、安全にループ処理を制御することができます。

for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break;
    }
    if (i % 2 == 0) {
        continue;
    }
    System.out.println("i = " + i);
}

この例では、iが5になったらループを終了し、iが偶数の場合は処理をスキップして次のループへ進む処理を行っています。

Javaで使えるループ構文の種類

Javaには複数のループ構文が用意されており、処理の内容や条件によって使い分けることが重要です。

それぞれのループ構文には特徴があり、正しく理解して使用することで無限ループを防ぎながら効率的に処理を行うことが可能です。

for文の基本概要

for文は繰り返す回数が決まっている場合に最適なループ構文です。

初期化、条件判定、変数の更新を1行でまとめて記述できるため、繰り返し処理の内容がシンプルであればあるほどfor文を使用することで可読性の高いコードにすることが可能です。

for文はカウンタ変数を用いて処理回数を管理しながら繰り返し処理を行います。

for (int i = 0; i < 5; i++) {
  System.out.println("カウント: " + i);
}

この例では、変数iが0から4までの値を取り、合計5回繰り返し処理が実行されます。

while文の基本概要

while文は条件が満たされている間繰り返し処理を実行する構文です。

繰り返す回数が決まっていない場合や、条件が変動する場合に使用されることが多いです。

条件が成立している間はループが継続し、条件が成立しなくなった時点でループを抜けます。

int count = 0;
while (count < 5) {
  System.out.println("カウント: " + count);
  count++;
}

この例では変数countが0から4までの間ループ処理が実行され、countが5になるとループを終了します。

do-while文の基本概要

do-while文は最低1回は必ず処理を実行した上で条件判定を行う構文です。

while文との違いはループ処理を実行した後に条件判定を行う点であり、条件の結果にかかわらず処理が1回は実行される特徴があります。

int count = 0;
do {
  System.out.println("カウント: " + count);
  count++;
} while (count < 5);

この例では、最初に処理が実行され、その後に条件判定が行われ、条件が成立している間はループが継続されます。

ループのネスト処理

Javaの実務では、二重・三重のループを用いた多次元データ処理や組み合わせ処理が頻繁に発生します。

ネストしたループの理解が不十分だと処理効率の低下や不具合の原因となるため、正しく理解して使いこなせることが重要です。

for文のネスト

for文のネストは二重ループを用いて多次元の配列処理や組み合わせの列挙処理を行う場合によく使用します。

外側のループが回るごとに内側のループが毎回初期化され、全ての組み合わせを網羅できる点が特徴です。

for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        System.out.println("i = " + i + ", j = " + j);
    }
}

この例では外側のiが0から2まで変化するごとに、内側のjも0から2まで繰り返し処理を行うため、合計9回の処理が実行されます。

ネストしたループでのbreak・continueの使い方

ネストしたループで外側ループを制御したい場合はラベル付きbreak・ラベル付きcontinueを使用します。

ラベル付きbreak

ラベル付きbreakは指定したループ全体を終了させます。

outer:
for (int i = 0; i < 3; i++) {
  for (int j = 0; j < 3; j++) {
    if (j == 1) {
      break outer; // 外側ループごと終了
    }
    System.out.println("i=" + i + ", j=" + j);
  }
}

ラベル付きcontinue

ラベル付きcontinueは指定したループの次回ループへスキップします。

outer:
for (int i = 0; i < 3; i++) {
  for (int j = 0; j < 3; j++) {
    if (j == 1) {
      continue outer; // 外側ループの次回ループへ移行
    }
    System.out.println("i=" + i + ", j=" + j);
  }
}

まとめると、breakはループを終了する、continueは次の処理へスキップするという違いがあり、ラベルを付けることで外側ループへ作用させることができます。ただしラベルはコードの可読性を下げる可能性があるため、本当に必要な場面だけで使用し、不要な場合は通常のbreak・continueで処理を組むことが大切です。

for, while, do-while の違いと使い分け

Javaでループ処理を使いこなすためには、for文、while文、do-while文の特徴を理解し、それぞれの使い分けを身につけることが重要です。

無駄な処理を避け、効率的にコードを記述するためにも、それぞれのループの条件判定のタイミングや用途の違いを把握しておく必要があります。

このセクションではfor文、while文、do-while文の違いと使い分けについてわかりやすく解説します。

それぞれの条件判定タイミングの違い

ループ処理では条件判定のタイミングが非常に重要です。

条件を評価するタイミングによって処理の流れが変わるため、各ループ構文の判定タイミングを理解することが無限ループ防止にもつながります。

処理前判定と処理後判定の違い

for文とwhile文はループ処理の実行前に条件判定を行います。条件が成立していない場合はループ処理が一度も実行されない可能性があります。

一方でdo-while文はループ処理を実行した後に条件判定を行うため、条件が成立しない場合でもループ処理が最低1回は必ず実行される点が大きな違いです。

// for文の例
for (int i = 0; i < 3; i++) {
    System.out.println("for: " + i);
}

// while文の例
int j = 0;
while (j < 3) {
    System.out.println("while: " + j);
    j++;
}

// do-while文の例
int k = 5;
do {
    System.out.println("do-while: " + k);
    k++;
} while (k < 3);

この例ではdo-while文だけが条件を満たさなくても1回処理を実行します。

実行回数と用途の違い

for文は繰り返し回数が決まっている場合に向いており、while文は条件が成り立つ間繰り返す処理に向いています。do-while文は必ず1回処理を実行したい場合に使います。この用途の違いを理解して使い分けることが重要です。

実行回数と用途の違い

  • for文:
    繰り返し回数が明確に決まっている場合に最適です。

  • while文:
    繰り返し回数が不定で条件が満たされる限り処理を続けたい場合に使用します。

  • do-while文:
    ユーザー入力のメニュー表示など最低1回は処理を行いたい場合に適しています。

このように用途に合わせて適切に使い分けることが重要です。

for, while, do-while の使い分け基準

それぞれのループ構文には適切な使い分け基準があります。

処理回数が決まっている場合や条件によって処理を繰り返す場合、最低1回の処理が必要な場合など状況によって選ぶループを判断することが無駄な処理を防ぎ、可読性の高いコードを記述するために必要です。

回数固定ならfor文

処理の繰り返し回数が固定されている場合はfor文を使用するのが最適です。

カウンタ変数を使って回数を管理できるため、配列の要素を順番に処理する場合などで活用されます。

for (int i = 0; i < 5; i++) {
  System.out.println("カウント: " + i);
}

この例では5回繰り返し処理が行われます。

回数不定ならwhile文

繰り返す回数があらかじめ決まっていない場合はwhile文を使用します。

条件が成立している間は処理を続けるため、ユーザーが正しい入力をするまで繰り返し処理を行う場面などで使用されます。

int count = 0;
while (count < 5) {
  System.out.println("カウント: " + count);
  count++;
}

この例ではユーザーがexitを入力するまでループを続けます。

必ず1回処理が必要ならdo-while文

do-while文は最低1回処理を実行した上で条件判定を行うため、必ず1回は処理が必要な場合に使用します。

メニュー表示後にユーザーが続行するかを確認する場合などで活用されます。

int selection;
Scanner scanner = new Scanner(System.in);
do {
    System.out.println("1: 実行 2: 終了");
    selection = scanner.nextInt();
} while (selection != 2);

この例では終了を選択するまでメニューが表示され続けます。

使い分けの具体的な判断ポイント

学習時や実務でループ構文を選ぶ際には、どの構文を使うべきか迷うことがあります。

場面ごとに使い分けの判断基準を覚えておくことで、無駄な処理を防ぎつつ、コードの可読性を維持することが可能になります。

学習時の判断基準

回数が決まっている場合はfor文を選ぶ、条件によって処理を続ける必要がある場合はwhile文を選ぶ、最低1回処理を行う場合はdo-while文を選ぶというシンプルな基準です。

使用するループの判断基準

  • 回数:回数が決まっている場合はfor文を選ぶ
  • 条件:条件によって処理を続ける必要がある場合はwhile文を選ぶ
  • 最低一回:最低1回処理を行う場合はdo-while文を選ぶ

この基準を身につけることで迷わずループ処理を記述できるようになります。

現場での判断基準

現場では可読性と保守性も重視する必要があります。

現場での判断基準

  • for文:
    繰り返し回数がわかる場合に見やすいため積極的に使用されます。

  • while文:
    処理の継続条件が複雑な場合やユーザー入力待ちの場合に使用されます。
  • do-while文:
    必ず1回は処理する必要があるメニュー表示や確認処理に使用されることが多いです。

コードの意図を明確に伝えるために適切な構文を選ぶことが大切です。

ループ制御で実際によくあるミスとbreak・continueの重要性

ループ処理の理解を深める際に、実務の現場で何が起きているのか知ることは非常に重要です。

実際に多くのJavaプログラムのレビューイーとしてコードレビューを行ってきた中で、一番多いミスがループからの抜け忘れです。

個人開発レベルであれば処理回数が数回から数百回で済むことが多いため、大きな問題に発展しにくい場合があります。

しかし、企業レベルの業務処理となると数万回から数十万回以上のループ処理が日常的に行われ、その影響は無視できないものとなります。

特定の条件を満たした際にループを終了させるための「break;」や、特定の条件を満たした際に処理をスキップするための「continue;」の記載漏れが非常に多く見受けられます。

この漏れにより無駄なループ処理が行われ、性能テストで処理時間の遅延やCPU負荷が高騰し、リリース直前に問題が顕在化することが多々あります。

結果として原因追跡に多大な工数を割くことになり、最悪の場合プロジェクト全体のスケジュールに影響を与えかねません。

現場で大恥をかかないためにも、ループ処理内での「break;」「continue;」の必要性を理解し、適切に記述する習慣を持つことが重要です。

以下は具体的な例です。

for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break;
    }
    if (i % 2 == 0) {
        continue;
    }
    System.out.println("i = " + i);
}

この例では、変数iが5になった時点でループを終了させるために「break;」を使用し、変数iが偶数の時はループ内の処理をスキップして次のループへ移行するために「continue;」を使用しています。

このように適切に使い分けることで、無駄なループを減らし、処理の効率化とリソースの節約を実現することができます。

誤った例(else if 使用・誤動作する)

特に注意すべき点として、breakとcontinueの条件判定をelse ifで繋げてしまう実装を現場で多く見かけます。

この例では、iが5のときにbreakが実行されますが、それ以外の場合に偶数であればcontinueが実行されます。

一見問題が無いように見えますが、両方の条件を同時に考慮すべきケースでelse ifを使うと誤動作の原因になります。下記の場合、i = 6, 8 のときに break 条件が成立しますが、else if のため、break と continue の両条件を同時評価できず、条件の優先順位次第で意図しない挙動になります。

for (int i = 0; i < 10; i++) {
    if (i >= 5 && i % 2 == 0) {
        break;
    } else if (i % 2 == 0) {
        continue;
    }
    System.out.println("i = " + i);
}

この書き方をしてしまうと、どちらか一方の条件しか評価されず、両方の条件を正しく評価できないため想定外の動作につながります。

breakの条件とcontinueの条件は独立して評価すべきであり、else ifで繋げることは避けるべきです。

処理の正確性と保守性を保つためにも、この点は注意してください。

無限ループを防ぐための基礎知識

Javaでループ処理を使うときに注意すべきなのが無限ループです。

無限ループが発生するとプログラムが停止せずCPUやメモリを消費し続け、最悪の場合はシステムが固まる原因となります。

無限ループを防ぐには原因を理解し、適切な確認と対策を行うことが重要です。

無限ループが発生する主な原因

無限ループは開発初心者から現場エンジニアまで誰もが経験するミスの一つです。

主な原因を理解し、どのような場面で発生しやすいのかを知ることで、ループ処理時のトラブルを減らすことが可能になります。

条件式の誤設定

無限ループの原因として最も多いのがループの条件式設定ミスです。

特にwhile文やfor文で条件式が常に真になるように記述してしまうと、ループが永遠に抜けられなくなります。

int count = 0;
while (count != 5) {
  System.out.println("カウント: " + count);
}

この例ではcountが更新されていないため、条件が常に真となり無限ループが発生します。

ループ内で変数の更新を正しく行うことと、条件式が適切であるかを必ず確認する必要があります。

カウント変数の更新忘れ

ループ変数の更新漏れも無限ループを引き起こす大きな原因です。

カウントアップや条件に関係する変数の更新をループ内で実行しないと、条件が変わらず永遠にループが続いてしまいます。

int count = 0;
while (count < 5) {
  System.out.println("カウント: " + count);
}

この例でもcountの更新が行われていないため、countは0のままで条件が常に成立し、無限ループとなります。

ループ内で適切にカウント変数を更新することが無限ループ防止の基本です。

無限ループを防ぐポイント

無限ループを防ぐためには、正しい変数管理だけでなく開発時のデバッグ活用やブレークポイントの設置などの確認方法を併用することが有効です。

実行前にミスを発見できる仕組みを作ることで開発効率が向上しトラブルを減らせます。

デバッグの活用方法

無限ループ発生時は変数の状態を把握することが重要です。

IDEのデバッグ機能を使用することで、ループ処理の途中で変数の値をリアルタイムで確認できます。

ループ条件を監視しながら処理の流れを追うことで、どこで条件が変わらずループが続いているかを発見しやすくなります。また、変数の更新が正しく行われているか、条件式が想定通り動作しているかを確認する際にもデバッグは有効です。

print文での確認だけでなく、デバッグツールを活用する習慣を身につけると問題解決までの時間を短縮できます。

ブレークポイントの設定と活用

IDEでの開発ではブレークポイントを設定し処理を一時停止できる機能があります。

ループ内にブレークポイントを設定することで、特定条件の際に処理を停止させ、変数の値やループ条件がどのようになっているかを直接確認可能です。

ブレークポイントは無限ループの発生場所を特定する際にも有効であり、無限ループが疑われる箇所で停止させることで原因を迅速に把握できます。手動で止めて変数を確認しながら条件修正を行うことで、無限ループの再発を防止できます。

現場で役立つループ処理の実践例

Javaのループ処理は基礎を理解するだけでなく、現場で実際に使える形で身につけることが重要です。

処理回数が決まっている場合、条件次第で変動する場合、必ず1回処理が必要な場合で適切なループを選び、実践的に使い分けることが開発効率を高めるポイントです。

配列・リスト処理で使うループ

配列やリストの要素を順に処理するときはfor文や拡張for文を使うと効率的です。

配列の添え字を利用した制御や、拡張for文で簡潔に記述する方法を覚えることで、コード量を減らしつつ可読性を高められます。

for文による配列処理例

配列の内容を順番に出力する場合、for文を使うことでインデックスを利用しながら処理を行えます。

要素数が決まっている配列の処理ではfor文が最適です。

int[] numbers = {10, 20, 30, 40, 50};
for (int i = 0; i < numbers.length; i++) {
  System.out.println("値: " + numbers[i]);
}

for文を使うことでインデックスを利用した柔軟な処理が可能になり、特定条件でスキップや処理の分岐も容易に行えます。

拡張for文(for-each)の活用

拡張for文は配列やコレクションのすべての要素を簡潔に処理したいときに便利です。

インデックス操作が不要で、読みやすいコードを記述できます。

int[] numbers = {10, 20, 30, 40, 50};
for (int num : numbers) {
  System.out.println("値: " + num);
}

全要素を順に処理するだけの場合は拡張for文を使うことでループの可読性を高められます。

ユーザー入力と入力チェックループ

ユーザー入力を受け付ける処理では、正しい入力が得られるまで繰り返し入力を求めることが必要になります。

while文を使うことで入力チェック処理を柔軟に記述できます。

while文による入力チェック例

ユーザーからの数値入力が特定範囲内であることを確認する際にwhile文を使います。

Scanner scanner = new Scanner(System.in);
int input = 0;
while (input < 1 || input > 5) {
  System.out.print("1から5の数字を入力してください: ");
  input = scanner.nextInt();
}
System.out.println("入力された値: " + input);

条件が満たされるまでループが続き、正しい値が入力された時点でループを終了します。

無効入力時のループ処理

文字列入力で「yes」「no」以外の無効な値が入力された場合に再度入力を求める処理にもループは活用されます。

Scanner scanner = new Scanner(System.in);
String input = "";
while (!input.equals("yes") && !input.equals("no")) {
  System.out.print("yes か no を入力してください: ");
  input = scanner.nextLine();
}
System.out.println("入力された値: " + input);

正しい入力を受け付けるまでループすることでユーザー入力の安全性を確保できます。

メニュー表示ループの具体例

簡易的なメニューを表示し、ユーザーが操作を続ける限りメニューを表示し続ける処理にはdo-while文が適しています。

必ず1回処理を実行し、ユーザーが続行を希望する場合のみ再表示する流れが実現できます。

do-while文を使ったメニュー表示例

メニューの選択肢を表示し、ユーザーが「n」を入力するまで処理を続ける例です。

Scanner scanner = new Scanner(System.in);
String choice;
do {
  System.out.println("1: 処理A");
  System.out.println("2: 処理B");
  System.out.println("n: 終了");
  System.out.print("選択してください: ");
  choice = scanner.nextLine();
} while (!choice.equals("n"));
System.out.println("プログラムを終了します。");

do-while文は条件にかかわらず最低1回は処理が実行されるため、メニュー表示処理に向いています。

再入力受付処理の流れ

再入力を受け付ける処理でもdo-while文が便利です。

確認ダイアログなどでユーザーが「yes」と回答した場合のみ再入力処理を続けることが可能です。

Scanner scanner = new Scanner(System.in);
String retry;
do {
  System.out.print("データを入力してください: ");
  String data = scanner.nextLine();
  System.out.print("もう一度入力しますか? (yes/no): ");
  retry = scanner.nextLine();
} while (retry.equals("yes"));
System.out.println("入力処理を終了します。");

再入力が必要な場合だけ繰り返す処理を簡潔に記述できるのがdo-while文の利点です。

まとめと次に学ぶべきこと

ここまでJavaにおけるループ処理の基礎知識、使い分けの基準、無限ループを防ぐための考え方について学んできました。

ループ処理はプログラムの基礎でありながら、現場でバグや不具合の原因になりやすい箇所でもあります。

理解したつもりでいると想定外の挙動を引き起こすため、確実に理解し正しく使い分けられることが重要です。

このセクションでは、これまで学んだポイントを振り返り、次に学ぶべきJavaの基礎知識について紹介します。

記事で学んだポイントの振り返り

ループ処理を学習する中で、単に文法を覚えるだけでなく、なぜそのループを使うのか、どのような場面で使い分けるのかを理解することが大切です。

この振り返りを通じて知識を定着させ、現場で使えるスキルにしていきましょう。

ループ処理使い分けの要点

ループ処理にはfor文、while文、do-while文の3種類があります。それぞれの使い分けのポイントは以下の通りです。

ループ構文特徴使う場面
for文回数固定のループ配列の繰り返し処理など
while文条件が成り立つ間繰り返す条件依存の処理
do-while文最低1回処理実行後条件判定メニュー表示・再入力処理

このように、それぞれの構文には適した場面があり、使い分けを正しく行うことがバグ防止につながります。

無限ループ防止のポイント

無限ループを防ぐためには次のポイントを意識することが重要です。

  • ループの条件式が正しく設定されているか確認する
  • カウント変数の更新を忘れない
  • IDEのデバッグ機能やブレークポイントを活用する
  • ループ内で変数の値を出力し、変化を確認する

これらを実践することで無限ループを未然に防ぎ、安全で安定したコードを書くことができます。

次に学ぶべきJavaの基礎知識

ループ処理をマスターしたら、次に学ぶべきは「クラスとオブジェクト」「例外処理とデバッグ」の基礎知識です。

これらは現場で実践的に使える知識であり、理解することでJavaエンジニアとしての基礎力が飛躍的に向上します。

クラスとオブジェクトの基本

Javaはオブジェクト指向言語であり、クラスとオブジェクトの概念は避けて通れません。

クラスは設計図、オブジェクトは実体という関係であり、変数やメソッドをまとめて管理することが可能です。

public class User {
    String name;
    int age;

    public void introduce() {
        System.out.println("名前: " + name + ", 年齢: " + age);
    }
}

このようにクラスを作成し、必要に応じてオブジェクトを生成し操作することで効率的なプログラムが書けるようになります。

例外処理とデバッグの基礎

プログラムを作成する際、エラーが発生することは避けられません。

そのため、例外処理を用いてプログラムの異常終了を防ぎ、安全に処理を行えるようにすることが重要です。

また、例外処理と合わせてデバッグの方法を学ぶことで、エラーが発生した際に迅速に原因を特定できるようになります。

try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("0で割ることはできません");
}

このように例外処理を行うことで、プログラムの予期せぬ停止を防ぎ、ユーザーに適切なメッセージを表示することが可能になります。

▶︎ この記事を読んだら、次は 「【Javaの基礎知識】クラス・オブジェクト・メソッドの基本をわかりやすく解説!」 を読むのがおすすめです!

よく読まれている記事

1

IT入門シリーズ 🟢 STEP 1: ITの基礎を知る(ITとは何か?) 📌 IT初心者が最初に学ぶべき基本知識。ITの概念、ネットワーク、OS、クラウドの仕組みを学ぶ ...

2

「私たちが日々利用しているスマートフォンやインターネット、そしてスーパーコンピュータやクラウドサービス――これらの多くがLinuxの力で動いていることをご存じですか? 無料で使えるだけでなく、高い柔軟 ...

3

この記事は、Linuxについて勉強している初心者の方向けに「Shellスクリプト」について解説します。最後まで読んで頂けましたら、Shellスクリプトはどのような役割を担っているのか?を理解出来るよう ...

-Javaの基礎知識(基礎編)