Javaでループを使う方法

著者は寄付プログラム「Write for Donations」の一環として、フリーおよびオープンソース基金を選んで寄付することにしました。

はじめに

プログラミングでは、反復的なタスクを書くことは一般的です。同じまたは類似のコードを必要な回数だけ書いて、コードのブロックを繰り返し実行する方法がひとつあります。しかし、このアプローチは完璧とは言えず、読みづらく保守が困難な重複したコードが生成されます。より良い選択肢は、ループを使用することです。

ループは繰り返しプログラムの流れを制御するための構造です。典型的なループには2つの部分があります。1つ目は真偽を判定する制御条件です。2つ目は条件が真であるか、条件が偽になるまで実行されるコードブロックです。真偽条件はコードブロックが実行されるたびに再評価されます。ループの終了条件は、このチュートリアルで学ぶ各種のループごとに異なります。

ループには、主にwhileループとforループの2つの主要な種類があります。どの種類かは、ループの構文とロジックによって決まります。whileループはブール条件に依存しています。この条件は一般的なものであり、条件が真である間はコードブロックが繰り返し実行されます。forループもコードブロックを繰り返し実行しますが、ループ条件は通常、整数変数の増加または減少に依存します。この変数が特定の目標値に到達すると、ループは終了します。

このチュートリアルでは、whileループとforループを使用して繰り返しタスクを作成し、それぞれの利点と欠点について学びます。

前提条件

このチュートリアルに従うためには、以下が必要です:

  • An environment in which you can execute Java programs to follow along with the examples. To set this up on your local machine, you will need the following:Java (version 11 or above) installed on your machine, with the compiler provided by the Java Development Kit (JDK). For Ubuntu and Debian, follow the steps for Option 1 in our tutorial How To Install Java with Apt on Ubuntu 22.04. For other operating systems, including Mac and Windows, follow the download options for Java installation.
    To compile and run the code examples, this tutorial uses Java Shell, also known as JShell, which is a Read-Evaluate-Print Loop (REPL) run from the command line. To get started with JShell, check out the Introduction to JShell guide.
  • Familiarity with Java and object-oriented programming, which you can find in our tutorial How To Write Your First Program in Java.
  • An understanding of Java data types, which is discussed in our tutorial Understanding Data Types in Java.

繰り返し処理する間

whileループは一般的なブール型の条件文を監視します。例えば、条件文は2つの整数変数が等しいか、または2つのオブジェクトが同じか、関連しているか、nullでないか、プログラムで確認できる他の条件を検証することができます。実際には、任意のブール式を使用できるため、whileループは非常に強力で広く使われています。

このセクションでは、whileキーワードを使用してJavaで最初のプログラミングループを作成します。ループを制御するために、単一のint変数を使用します。int変数はxと呼ばれ、初期値は3です。xが0よりも大きい限り、ループはコードブロックを続けて実行します。このコードブロックでは、xの値が表示され、さらに重要なのは、各実行ごとにポストデクリメント(–演算子を使用して)されます。このポストデクリメント操作により、現在のループはいくつかの実行後に終了します。それがなければ、ループは無限に続きます。

Info

情報:このチュートリアルの例のコードに従って進めるためには、ローカルシステムでJShellツールを開いてください。jshellコマンドを実行することで開きます。それから、jshell>プロンプトの後に例を追加してENTERキーを押すことで、コードをコピー、貼り付け、または編集することができます。JShellを終了するには、/exitと入力してください。

このコードをテストするために、以下の行をjshellに貼り付けてください。

  1. int x = 3;
  2. while (x > 0) {
  3. System.out.println(“x is ” + x–);
  4. }

 

最初の行で、変数xを定義します。

ループは2行目でwhileキーワードで始まります。条件文(x > 0)がループを制御します。それはxが0より大きいかどうかを比較します。その後に開始括弧{が続き、コードブロックの開始を示します。このコードブロックは条件がtrue(x > 0)の間、繰り返し実行されます。

コードブロックの中で、3行目のSystem.out.println(“x is ” + x–);という文は、println()メソッドを使用してxの現在の値を出力します。println()メソッドの引数の中で、xはコードx–によって1だけ減少されます。各実行ごとに、xは1ずつ減少します。(Javaで最初のプログラムを書く方法については、当社のチュートリアルをご覧ください。)

コードのブロックは、最後の行にある閉じ波括弧 } で終わります。これは同時にループの終わりでもあります。

このコードをjshellで実行すると、以下の出力が表示されます。

Output

x ==> 3 x is 3 x is 2 x is 1

最初の行は、xが3の値を受け取ったことを確認しています。その後の行では、xの値が3回出力され、毎回1ずつ減少します。xが3、2、1の値になるのは3回の反復のみです。xが0に達した時点で条件文x > 0が満たされなくなるため、ループは終了します。この時点でループが終了し、それ以外には何も出力されません。

前の例は、ループを作成するための一般的な方法です。ループの意図は明確であり、終了条件も簡単です: x > 0です。理論的には、追加の変数や比較(たとえば、x > 0 かつ y < 0)を追加することで条件をより複雑にすることもできますが、これはクリーンコードの観点からはベストプラクティスとは考えられません。複雑な条件はコードを追いにくくし、理解しにくくする一方、ほとんど、あるいはまったく価値をもたらしません。

do-whileループ

do-whileループは、whileループよりも人気はありませんが、それでも広く使用されています。do-whileループはwhileループに似ていますが、1つの重要な違いがあります:コードブロックが先に実行され、その後にループ条件が評価されます。

注意として、whileループは最初に条件を評価し、条件が満たされない場合はコードブロックを実行しません。しかし、do-whileループでは、ループ制御条件が評価される前に少なくとも1回はコードブロックが実行されます。もし条件が真ならば、ループは条件が満たされなくなるまで追加の繰り返しを続けます。そのため、do-whileループは質問をして正しい答えが得られるまでのみループを終了させるような場合に便利です。

このセクションでは、前のセクションでのwhileループに似たdo-whileループを作成します。int変数はxと呼ばれ、初期値は3です。しかし、今回は条件が逆転しています(x < 0)、そして条件が評価される前にコードブロックが実行されます。

JShellを開き、do-whileループを追加してください。

  1. int x = 3;
  2. do {
  3. System.out.println(“x is ” + x–);
  4. } while (x < 0);

 

このコードは、前のセクションのwhileループといくつかの類似点があります。まず、変数xの割り当てがありますが、再び3です。

2行目では、キーワード「do」とコードブロックのための開始ブラケット「{」を使ってループが開始されます。3行目では、println()メソッドを使ってxの値が表示されます。println()メソッドでは、さらにpostdecrement演算子–を使ってxの値をデクリメントします。

最後の行には、コードブロックの閉じ括弧}があり、続いて条件文(x < 0)を持つwhileキーワードが続きます。これが前のwhileループと異なる部分です。ここでは条件が反転しています:xは0より小さくなければなりません。前の例では、条件式はxが0より大きい必要がありました。この変更により、条件が満たされなくてもコードブロックは一度だけ実行されることが示されます。

jshellでこのコードを実行すると、以下の出力が表示されます。

Output

x ==> 3 x is 3

最初の行では、xの値が3であることを確認しています。2行目では、xが3であると表示されています。このdo-whileループの特異性は、条件(x < 0)が満たされなくても、コードブロックが少なくとも一度は実行される点です。この無条件の実行は必ずしも常に望ましいわけではないため、do-whileループを使用する際には注意が必要です。この注意点のため、do-whileループはあまり頻繁に使用されません。

ループについて

代替のループ構造として、forループがあります。これはwhileループと同じく条件の下でコードのブロックを繰り返し実行するために使用されますが、より多くのオプションがあります。ループ制御条件では、一時変数を追加し、制御条件を定義し、一時変数の値を変更することができます。これにより、ループを制御するすべての要素を結びつけ、何かを見落としたりミスをする可能性を減らすことができます。これにより、コードをきれいで理解しやすく保つことができます。より厳格なスタイルに従ってコードを書きたい場合には、forループの方が適しています。

以下は典型的なforループです。

  1. for (int x = 3; x > 0; x–) {
  2. System.out.println(“x is “ + x);
  3. }

 

最初の行にはforキーワードでループが始まります。括弧内の条件文には3つの部分があります。

  • int x = 3 defines a variable (x). Defining a temporary variable here is convenient because they are only needed for the loop, so it makes sense to integrate them into the loop. In contrast, when you used a while loop, you had to declare the variable separately before the loop.
  • x > 0 is the condition that has to be met for the block of code to be executed. In this case, x has to be bigger than 0. This part is similar to the while loop control statement, which only contains the condition to be evaluated.
  • x– is the action taken during each successful iteration. In this case, a postdecrement operation decreases the value of x after each successful execution.

2行目のSystem.out.println(“x is ” + x); の文は、println() メソッドを使用してxの値を出力します。 xの値は変更されずにそのまま出力されます。一方、whileループ内でxの値を操作するためにprintln() メソッドを使用しました。しかし、これは必要ありません。なぜなら、条件文の3つ目の部分で既にpostdecrement操作が行われているためです:x–。

3行目は、コードのブロックと全体のループ構造を、閉じ括弧}で終了させます。

このコードをjshellで実行すると、次の出力が表示されます。

Output

x is 3 x is 2 x is 1

出力は、コードブロックが3回実行されたことを確認します。最初の実行では、xの値は3です。2回目の実行では、xは2であり、3回目の実行ではxは1です。3回目の実行後、xは0になり、コードブロック(xの値を表示する)は実行されずにループが終了します。

このforループは、whileループと同じ結果を得ることができます。パフォーマンスとリソースの使用に関しては、違いはほとんどありませんので、どちらのループを使用するかは個人の好みの問題です。ただし、反復回数がわかっている場合は、通常はforループを好んで使用します。なぜなら、コードをより詳細に追うことができるからです。

foreachループ

foreachループは他のループと似ていますが、少ないコードで値のグループを繰り返し処理するために特別に設計されています。値のグループがある限り、それらの数や繰り返しの進行を追跡する必要なく、それらを逐一取り出して表示することができます。foreachループは、グループに値がある場合にそれらを一つずつ取り出して提供してくれます。

ほとんどのプログラミング言語には、foreachループの便利なショートカットがあります。Javaでは、独自のforeachキーワードはありませんが、代わりにforキーワードが使用されます。ただし、foreachの条件文は通常のforループと異なります。次にご確認いただけます。

foreachループで作業するためには、値のグループを使用する必要があります。そして、その目的には配列が適しています。配列は、同じ型の値を含むオブジェクトです。以下の例では、int値を含む配列を使用します。

以下のコードをjshellに追加してください。

  1. int[] numbers = {0, 1, 2};
  2. for (int x: numbers) {
  3. System.out.println(x);
  4. }

 

最初の行で、0、1、2の3つの整数を含んだint配列を作成します。

2行目でforeachループがforキーワードで始まります。次に、一時変数int xを定義しますが、その後ろにコロンが続きます。コロンはforeach操作のショートカットとして使用されます。(foreachループ文は、Javaで唯一コロンが使用される場所です。)コロンの後ろには、配列などの値のコレクションがあります。

foreachループ文の後には、numbers配列の各値に対して実行されるコードブロックがあります。この場合、System.out.println(x)の文は、println()メソッドを使用してxの値を出力し、それはnumbers配列の各値を参照します。

上記のコードをjshellで実行すると、以下の出力が表示されます。

Output

numbers ==> int[3] { 0, 1, 2 } 0 1 2

最初の行では、0、1、2という値を含むnumbersという配列が定義されていることが確認されます。以下には、配列の値がそれぞれ新しい行に出力されます:0、1、2。

他のループを使用することは、主に個人の選択の問題ですが、foreachループは値のグループを反復処理するための事実上の標準です。forループやwhileループを使用してforeachループの代替を作成することも可能ですが、それには大きな努力とデータ構造の深い理解が必要であり、それほど価値がありません。

無限ループ

無限ループは、制御条件が常に真の場合に終了しないforループまたはwhileループです。

以下は、無限のwhileループの一般的な例です。

  1. while (true) {
  2. System.out.println(“This will print forever.”);
  3. }

 

最初の行は典型的なwhileループのように見えますが、x > 0のような条件ではなく、単にtrueという値があります。この場合、制御条件を評価する必要があるときには常にtrueが直接返されます。この場合、ループを終了する方法がないため、永遠に続きます。二行目にはSystem.out.println(“This will print forever.”);という文が含まれており、println()メソッドを使用してテキスト「This will print forever.」を表示します。

上記のコードをjshellで実行すると、次の出力が表示されます。コードを終了するまでに素早くキーボードのCTRL+Cの組み合わせで終了する準備をしてください。そうしないと、無限に続きます。

Output

This will print forever. This will print forever. …

最初の2つの繰り返ししか表示されませんが、この出力はCTRL+Cを押して手動で終了するまで続きます。

無限ループの例では、ブール値の代わりに単一の真の値が配置されることで、そのようなループを作成する明確な意図があります。過去にはこのようなループが人気があり、レガシープロジェクトでも見かけるかもしれません。まだこのような無限ループを作成することはできますが、タイマータスクなどの連続実行タスクを作成するためのより良い方法があります。タイマータスクの方が洗練されており、より多くのオプションを提供しているため、タイマータスクが推奨されています。

残念ながら、無限ループは時に意図されていないこともあります。間違いをして無限ループを引き起こすことがあります。以下のコードを考えてみてください。

  1. int x = 3;
  2. while (x > 0) {
  3. System.out.println(“x is ” + x);
  4. }

 

上記のコードは、このチュートリアルの最初の例と非常に似ています。最初の行では、変数xを値3で定義しています。

2行目にはwhileキーワードと制御条件があり、それはループがx > 0が真である限り続くべきであることを示しています。

3行目の System.out.println(“x is ” + x); という文は、println() メソッドを使用して x の値を出力します。しかし、このチュートリアルの最初のセクションでの while ループの例とは異なり、現在の例では x の後置減算操作がありません。そのため、このループを jshell で実行すると、次のような連続した出力が得られます。

Output

x is 3 x is 3 …

この行は、CTRL+Cでループを終了するまで無限に繰り返されます。これらの意図しない無限ループは、プログラムのクラッシュやプログラムを実行しているマシンの過負荷を引き起こす可能性があるため、危険です。そのため、ループを作成する際には注意して、終了可能な終了条件があることを確認する必要があります。現在の例では、ループを終了するために、各ループでxが減少するようにする必要があります。

結論

このチュートリアルでは、繰り返しタスクを作成するためにループ構造を使用しました。whileループとforループを使用する適切な場面と、それらを使ったいくつかのコード例を学びました。また、クリーンなコードのためのベストプラクティスやループに関連する一般的な落とし穴を避ける方法も学びました。

Javaについてもっと詳しく知りたい場合は、私たちの「Javaでのコーディング方法」シリーズをご覧ください。

コメントを残す 0

Your email address will not be published. Required fields are marked *