【Java入門】whileとdo whileの使い方 - ループ処理の注意点やforとの使い分けを解説
正しく処理されるだけでなく、見やすいコードや速く動作するコードを書くためにはそれぞれの違いを理解しておく必要があります。ここでは言語をJavaに絞って、while文の使い方と、forとの違いを解説します。
正しく処理されるだけでなく、見やすいコードや速く動作するコードを書くためにはそれぞれの違いを理解しておく必要があります。ここでは言語をJavaに絞って、while文の使い方と、forとの違いを解説します。
スキルアップ
2020/12/11 UP
- プログラミング
- SE資格・スキル
- 入門
- Java
同じ処理を連続して行う場合、繰り返し処理をループで書くと無駄な処理がなく、コードも分かりやすくなります。この繰り返し処理で最も一般的なのはfor文ですが、その他にwhileを使う繰り返しもあり、どれを使うか迷ってしまうこともよくあります。
for文でもwhile文でも、同じ処理を実行するコードを書くことが可能ですが、選んだものによってプログラムの実行量を減らしたり、メンテナンス性の高いプログラムになったりします。
正しく処理されるだけでなく、見やすいコードや速く動作するコードを書くためにはそれぞれの違いを理解しておく必要があります。ここでは言語をJavaに絞って、while文の使い方と、forとの違いを解説します。
Javaのwhile文とは
Javaで使われるwhile文はwhileとdo whileの2種類あります。whileは「〜の間」という意味で、判定条件が成立する間、処理を繰り返す構文です。
whileの場合
public static void whileLoop01() { int i = 0; while (i < 3) { System.out.println("i=" + i + " の処理"); ++i; } }
do whileの場合
public static void whileLoop02() { int i = 0; do { System.out.println("i=" + i + " の処理"); ++i; } while (i < 3); }
サンプルのメソッド、whileLoop01はwhileの構文です。変数iが0から始まり3より小さい間は処理が繰り返されます。
whileLoop02の処理はdo whileの構文です。変数iが0から始まり、3より小さい間に処理が繰り返されることは変わりません。do whileは条件判定される前に1度処理が実行される構文のため、条件に該当するかどうかに関係なく、1周はループが回ります。
条件はboolean型にする
public static void whileLoop03() { int i = 0; // こちらはエラーになる while (i) { } // こちらが正しい表記 while (i < 10) { } }
条件式はtrueかfalseのどちらかで結果が出るboolean型になるように記載します。そのため、サンプルコードのwhile (i)の書き方では、比較演算子や論理演算子が使われていないので、iの値を評価することができず、エラーとなります。
while (i > 0)のように、trueまたはfalseが判定できる形で条件式を記載しましょう。条件を記述する比較演算子、論理演算子の種類や使い方については以下の記事も併せてご確認ください。
Javaのwhile文の書き方
Javaのソースコードでよく使われるwhile文の書き方を、サンプルを挙げながら解説していきます。ループを抜けることや、次の繰り返しに進む指示を使うことで、制御の流れを変えていくのが基本形です。
while文の基本形
public static void whileLoop04() { int a[] = new int[10]; int i = 0; while (i < 10) { a[i] = i * 10; ++i; } System.out.println("a[9]: " + a[9]); }
このサンプルは配列aにi×10の結果を10個詰めていき、whileの処理を抜け出した後、配列の9番目の要素(a[9])を出力します。
配列は、要素の個数を宣言し、そこにwhile文でループが回った結果を順番に格納していける箱のようなものです。配列がないとそれぞれの結果を別々の変数に格納する必要がありますが、配列を使えばループを回しながら結果を格納でき、まとめて管理が可能なので分かりやすくなります。while文などのループではよく使われるので一緒に覚えてしまいましょう。
do while文の基本形
public static void whileLoop05() { int a[] = new int[10]; int i = 0; do { a[i] = i * 10; ++i; } while (i < 10); System.out.println("a[9]: " + a[9]); }
このサンプルは、上述のwhileをそのまま do while に置き換えたものです。配列aにiが0から順番に詰められていき、iが10より小さい間、whileの処理が実行されます。do while文は先に解説した通り、1度は必ず処理が実行される構文なので、条件判定を記載する位置に注意しましょう。
breakでwhileを終了する
whileの場合
public static void whileLoop06() { int a[] = {10, 3, -1, 5, 20}; int i = 0; while (i < 5) { if (a[i] < 0) { System.out.print("i=" + i + " でループを抜ける"); System.out.println(" a[" + i + "]: " + a[i]); break; } System.out.println("i=" + i + " の処理"); ++i; } }
do whileの場合
public static void whileLoop07() { int a[] = {10, 3, -1, 5, 20}; int i = 0; do { if (a[i] < 0) { System.out.print("i=" + i + " でループを抜ける"); System.out.println(" a[" + i + "]: " + a[i]); break; } System.out.println("i=" + i + " の処理"); ++i; } while (i < 5); }
breakの書かれた箇所に来ると、処理が終了しループを抜けだすことができます。サンプルコードは配列aに5個の要素、10、3、-1、5、20を詰めるところまではどちらのコードも同じです。
whileLoop06のメソッドはwhile文のサンプル、whileLoop07のメソッドはdo while文のサンプルとなっています。breakを書く位置を間違えると条件判定する前に処理が終わってしまったり、予期せぬところでループが止まってしまったりする原因となるので注意しましょう。
continueで次のwhileループへ
whileの場合
public static void whileLoop08() { int a[] = {10, 3, -1, 5, 20}; int i = 0; while (i < 5) { if (a[i] < 0) { System.out.println("i=" + i + " の処理を中断 a[" + i + "]: " + a[i]); ++i; continue; } System.out.println("i=" + i + " の処理"); ++i; } }
do whileの場合
public static void whileLoop09() { int a[] = {10, 3, -1, 5, 20}; int i = 0; do { if (a[i] < 0) { System.out.println("i=" + i + " の処理を中断 a[" + i + "]: " + a[i]); // この ++i を忘れると無限ループ ++i; continue; } // contiuneが走るとここはスキップされる System.out.println("i=" + i + " の処理"); ++i; } while (i < 5); }
continue文はcontinueより後に書かれた処理を実行せずに、次の繰り返し条件の判断を行います。ここでは、配列の数値が0以下の場合、continueのあるif文が処理されます。if文に入り System.out.println() を実行した後 continueされ、後続の System.out.println() は実行されずにスキップされます。
なお、continue文より後に書かれた処理はスキップされるので、continueの前に変数iの更新を忘れないようにしましょう。更新を忘れると、iの値は初期値0のままで増えることがなく、無限ループになってしまうので注意しましょう。
無限ループをわざと作る
while文の条件判定はboolean型の値であればプログラム的にエラーを起こすことはありません。while (true)、while(1)のような形で、boolean型の判定結果を固定で記載してしまうこともできますが、この場合終了条件の記載がないのと同じ状態なため、ループが無限に回り続けます。
実際のプログラムで無限ループを起こすと、メモリがオーバーフローするなど、システム全体に関わるエラーを起こしかねないので、実装してはいけないコードです。間違えて書いてしまった場合も、一度実行してみれば無限ループになっていることは分かるので、書いたコードは必ず確認しましょう。
while の場合
public static void whileLoop10() { int i = 0; while (true) { System.out.println("i=" + i + " の処理"); ++i; } }
do while の場合
public static void whileLoop11() { int i = 0; do { System.out.println("i=" + i + " の処理"); ++i; } while (true); }
Java のwhile文とfor文の使い分け
ループを回す処理はwhile文でもfor文でも書くことができますが、読みやすさを考えるとどちらかに決まることが多いです。それぞれサンプルを列挙して解説します。
while文のほうがよい場合
while文はループの回数が決まっていない場合に使うと便利です。以下のサンプルの場合、読み込み元となっているtest.txtに何文字入っているかは分かりません。読み込んだ文字を順番に変数chに格納していき、読み込む文字がなくなるまで処理が続行されます。
for文はループを回す回数を指定する必要があるので、同じ処理をfor文で書くのなら、test.txtに何文字入っているかを別の処理で数え、それを終了条件とすることになります。
public static void whileLoop12() { try { FileReader fr = new FileReader(new File("test.txt")); int ch = fr.read(); // 1文字読み込み while (ch != -1) { //読み込んだ文字があれば System.out.println((char)ch); ch = fr.read(); // 次の文字を読み込み } } catch (Exception e) { System.out.println(e); } }
一方do whileは必ず1回は処理をしたい場合に便利です。以下のサンプルコードであれば、変数valueを一度処理しないまま表示させることで、処理開始時のvalueの値を知ることができます。そのvalueに対して7を足していき、valueが100より小さい間は処理が回り続けることになります。
public static void whileLoop13(int value) { do { System.out.println("value: " + value); value += 7; } while (value < 100); }
for文のほうがよい場合
ループを回す回数が決まっているときはfor文のほうが使い勝手がいいです。以下のサンプルコードはfor文もwhile文も同じ動きをしますが、for文はループ開始時の値、終了条件、変数の増減がforの後にまとまって記載されています。ループが行われる条件を探さずに確認できるのでfor文のほうが簡潔に記載することが可能です。
public static void whileLoop14() { // forの方が簡潔 for (int i = 0; i < 10; i++) { System.out.println("i=" + i + " の処理"); } }
Javaのwhile簡単!サンプルをコピーして実践しよう
ループ文の中で、whileの使用頻度はそれほどありませんが、覚えれば簡単に使える構文です。条件判定の結果だけでなく、breakやcontinueとも一緒に使われることが多いので、セットで覚えておきましょう。for文と比較しながら使えるとJavaのループを使いこなすことができます。