2018年2月25日日曜日

お馴染みのforループですが...

 Cにも、C++にも、Javaにも出てくるお馴染みのforループですが、初心者にはその動作が分かり難い場合があるようです。英国ケント大学が開発しているBlueJというJavaの開発環境に関するフォーラムで、昨日ちょっと話題になった投稿を基に、以下に書きます。

-------------------------------------------
for(int i = 0; i<10; i++)
    System.out.println(i);
-------------------------------------------

 上記の例は、普通に使っているforループです。0〜9までをプリントするだけなのに、ローカル変数iを定義していて、しかも、それが4回も出現しています!また、その動作を確認しようと思って、各行にブレークポイントを設定してデバックしても、forとSystem.out...の2行が交互に実行(表示)されるだけで、有用な動作情報が得られません。そこで、

-------------------------------------------
for(
    int i = 0; 
    i<10; 
    i++
)System.out.println(i);
-------------------------------------------

 このように、forの中にあるローカル変数iの初期化、範囲検査、回数の増加操作を3行に分割します。そうして、それぞれにブレークポイントを設定してデバッグをすると、動作が良く分かります!という投稿でした。なるほど、確かにループ処理の動作を把握しやすい、という反応が多かったです。

 ところで(この投稿では言及されていませんが)、このようなfor文は何とも書きたくないですね。とても重苦しいシンタックスです。最近のJavaでは下記のようにも書けると知ると、従来のforは使いたくないですね。下記の例は、上記と同じことをするJava SE8 以降の書き方の一例です。ラムダ式とストリーム Lambda & Streams(ラムダ式は直接ここにはありませんが)が登場しているのです。

-------------------------------------------
IntStream.range(0, 10)
.forEach(System.out::println);
-------------------------------------------

 上のような従来型forループにあったローカル変数は全く使っていません!元々不要だったんですね。いや違うでしょう。従来に対する発想の転換の結果と言えるでしょう。よく言われることなのですが、次の違いがあります。
従来のforループ:howto、すなわち、どう処理するかの観点に立っている。ループインデックスをどのように制御して使うのか。
ラムダ・ストリーム:what、すなわち、何をするのかの観点に立っている。必要なデータを揃えて、それらに対して何をしたいのか、何を適用するのか。

0 件のコメント:

コメントを投稿