【Java Silver対策】制御構造を学習しよう!【例題にも挑戦!】後編

資格学習
ハック
ハック

こんにちは、運営者のハックです。

今回はデイトラJava Silver対策編「第4章の対策」の学習記録のうち前半部分を紹介します。

前回から引き続き「第4章 制御構造」について学習します。

第4章では主にループ(for文、拡張for文、while文、do-while文)、そしてジャンプ(break文、continue文、return文)について解いていきます。
今回は後半部分であるループのうち拡張for文、ジャンプ(break文、continue文、return文)について解きました。

引き続き解説の参考と例題の引用は【黒本】と呼ばれる「徹底攻略Java SE 11 Silver問題集」から行っていきます。

拡張for文

拡張for文についてはJavaコース初級 基礎編Day9「繰り返し、配列、拡張for文、List、Map」でも紹介しましたが、今回はさらに深掘りして学習します。

拡張for文(enhanced for loop)は、Java 5から導入された構文で、配列やコレクションフレームワーク内の要素を簡単に取り出して処理するために使われます。これにより、標準的なfor文を使う場合に比べてコードが読みやすく、書きやすくなります。

ルールと特徴

  1. 配列やIterableインターフェースを実装するオブジェクトのみ使用可能: 拡張for文は、配列やjava.lang.Iterableインターフェースを実装する任意のクラス(ほとんどのコレクションクラスがこれに該当)に対して使用できます。
  2. 単一の要素に対する操作専用: 拡張for文は、取り出した各要素に対して操作を行う場合に適しています。要素の削除や追加など、コレクション自体を変更する操作はできません。
  3. 読み取り専用: 拡張for文で取り出された要素に対する変更は、その要素のコピーに対して行われるため、元の配列やコレクションの内容を変更することはできません(ただし、オブジェクトのプロパティを変更することは可能です)。
モナ
モナ

実際に拡張for文の例題を見てみましょう。

次のプログラムをコンパイル、実行したときの結果として、正しいものを選びなさい。(1つ選択)

1. public class Main {
2.    public static void main(String[] args) {
3.        String[] array = {"A", "B", "C"};
4.        for(String str : array){
5.           str = "D";
6.        }
7.        for(String str : array){
8.           System.out.println(str); 
9.        }
10.    } 
11. } 

A. 「DDD」と表示される。
B. 「ABC」と表示される。
C. コンパイルエラーが発生する。
D. 実行時に例外がスローされる。

「徹底攻略 Java SE 11 Silver 問題集」より抜粋
ねこ奈
ねこ奈

拡張for文が2か所あるのにゃ。

確かfor文の括弧内で変数を宣言しても、元の変数には影響がなかったはずなのにゃ。

だから「array」の中身自体は変わってないから出力されるのは、どっかの王様の名前みたいな「DDD」じゃなくて、「ABC」と出力されると思うのにゃ。つまり選択肢Bが正解だにゃ!

モナ
モナ

…DDD?PPPな国にいるあの大王のことね

選択肢Bで正解です!

拡張for文では繰り返し処理を実行するために一時的に変数を使っています。なので、変数の参照を変更しても、集合(配列/コレクション)には影響しません。

なお、変数の参照先のオブジェクトを変更した場合は影響します。

ジャンプ(break文、continue文、return文)について

ジャンプステートメント(break文、continue文、return文)は、プログラムの制御フローを変更するために使用されます。これらのステートメントは特にfor文などのループやスイッチ文内で効果を発揮し、コードの実行フローを即座に変更するために使われます。

以下、それぞれのステートメントについて詳しく説明します。

break文

用途:
break文は、最も内側のswitch文やループ (for, while, do-while) から抜け出すために使用します。

動作:
break文が実行されると、プログラムはswitch文やループのブロックを即座に終了し、次の文へ処理を移します。

for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break; // iが5になるとループから抜け出す
    }
    System.out.println(i);
}

の例では、iが5に達するとbreak文が実行され、ループが中断されます。その結果、0から4までの数が出力され、5以降は出力されません。

continue文

用途:
continue文は、ループの現在の繰り返しをスキップし、ループの次の繰り返しに直接進むために使用します。

動作:
continue文が実行されると、ループ内の残りのコードはスキップされ、ループの更新式へと進んだ後、次の繰り返しの条件判定へ移ります。

for (int i = 0; i < 10; i++) {
    if (i % 2 == 0)) {
       continue; // iが5になるとループから抜け出す
    }
    System.out.println(i);
}

この例では、iが偶数の時continue文が実行され、System.out.println(i);はスキップされます。結果として奇数のみが出力されます。

return文

用途:
return文は、現在のメソッドから抜け出し、メソッドを呼び出した場所へ戻るために使用します。また、必要に応じて値を返すこともできます。

動作:
return文が実行されると、そのメソッドの実行は終了し、オプショナルで値を呼び出し元に返します

int add(int x, int y) {
    return x + y; // x + yの計算結果を返す
}

System.out.println(add(5, 3)); // この場合、8が出力される

この例では、addメソッドが5と3の和を計算し、return文によって8が返されます。その後、System.out.printlnでその値が出力されます。

ラベルの使用

ラベルとは、プログラム内の特定の文やブロックに名前をつけて参照できるようにする機能です。
ジャンプステートメント(break文、continue文)をラベルと共に使用することで、ネストされた複数のループ間でより精密な制御が可能になります。ラベルを使用すると、プログラムの特定のブロックに名前を付けて参照することができ、これにより複雑なフロー制御やエラー処理が容易になります。

以下ではbreak文での事例を紹介します。

outer: // ラベル名
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        if (i * j > 2) {
            System.out.println("Breaking at i=" + i + ", j=" + j);
            break outer; // ラベルouterを指定して外側のループを終了
        }
        System.out.println(i + ", " + j);
    }
}
System.out.println("Finished");

//出力結果
0, 0
0, 1
0, 2
1, 0
1, 1
Breaking at i=1, j=2
Finished

この例では、iとjの積が2を超えた場合、外側のループ(ラベルouterがつけられたループ)を終了します。これにより、i=2のループが始まることはありません。

モナ
モナ

ジャンプステートメントとラベルを組み合わせた例題がありましたので確認してみましょう。

次のプログラムをコンパイル、実行したときの結果として、正しいものを選びなさい。(1つ選択)

1. public class Main {
2.    public static void main(String[] args) {
3.        int total = 0;
4.        a: for(int i = 0; i < 5; i++){
5.           b: for(int j = 0; j < 5 ; j++){
6.              if(i % 2 ==0) continue a;
7.              if(3 < j) break b;
8.              total += j;
9.            }
10.        }
11.        System.out.println(total); 
12.    } 
113. } 

A. 6が表示される。
B. 12が表示される。
C. 20が表示される
D. コンパイルエラーが発生する。
E. 実行時に例外がスローされる。

「徹底攻略 Java SE 11 Silver 問題集」より抜粋
ねこ奈
ねこ奈

breakとcontinueの2つのジャンプステートメントがあるのにゃ!
しかも前回学習した二重ループも使われているし、複雑な問題だにゃあ。えーっとぉ…・

「 if(i % 2 ==0) continue a;」は「iが偶数と時はaの処理をスキップする」という意味かにゃ。

「if(3 < j) break b;」は「jが3より大きい場合はbの条件から抜ける」って意味だにゃ。

そうすると…ひょっとしてこの例題って表を作って考えた方がいいのにゃ?

モナ
モナ

お察しのとおりです。iとjの値ごとに表を作って考えてみましょう。

ちなみにねこ奈の認識はほぼ正しいですが、正確には「 if(i % 2 ==0) continue a;」は「iが偶数の時、ラベルaまでコントロールを戻し、次の繰り返しを開始する」という意味であり、「if(3 < j) break b;」は「jが3より大きい場合、ラベルbが付けられたループやブロックを終了する」という意味になります。

iの値jの値結果totalの値
continueでラベルaへ
totalに0を加算する
totalに1を加算する
totalに2を加算する
totalに3を加算する
breakでラベルbへ
continueでラベルaへ
totalに0を加算する
totalに1を加算する
totalに2を加算する
totalに3を加算する12
breakでラベルbへ12
continueでラベルaへ12
ねこ奈
ねこ奈

表にしたらスッキリ見やすくなったのにゃ!

モナ
モナ

表から正解は選択肢Bであることが分かりますね。

breakやcontinue、ラベル、二重ループを組み合わせたコードの問題では、ラベルが付けられている箇所、breakやcontinueがどのラベルに移動するかを確認するようにしましょう。

まとめ  複雑な問題は表にして考える

今回は第4章「制御構造」の後半部分であるループのうち拡張for文、ジャンプ(break文、continue文、return文)について解きました。

ハック
ハック

二重ループなど複雑な条件式の問題は場合分けや表にして考えた方が早かったりします。

本番でも時短させないで落ち着いて正確に問題を解きたいですね。

以上で今回の学習記録を終えます。

ここまでご覧いただきありがとうございました。

コメント

タイトルとURLをコピーしました