forEachはJava 8で追加された新機能のうちの一つです。Java 8ではこの他にもラムダ式やStream APIなどの機能が追加されています。
ラムダ式やStream APIに関しては詳しく解説はいたしませんので、ラムダ式やStream APIがわからないという方は別の記事で調べてみてください。
forEach文はプログラミング言語では比較的使用頻度の高い「繰り返し処理」を行う上で使用される文です。ことJavaに関してはJava5.0以降で利用可能となった拡張forがこれに相当する関数でしたが、Java8の登場によりメソッドとして使えるようになりました。
今回はこのforEachにスポットをあてながらしっかりと説明していきたいと思いますのでお付き合いください。
記述ルール
まずは次のコードを見てください。
for (String s : list) { System.out.println(s); }
これはJava7以前のfor文を使ったコードです。これだけ見ると別段難しいコードではありませんが、このコードだけで3行です。
では次のコードを見てください。
list.forEach(s -> System.out.println(s));
こちらはJava8以降で使用可能となったforEachメソッドを使ったコードです。上下とも同じ処理ですが、forEachメソッドを利用することでスッキリとしたコードに仕上がっています。実際のプログラミングでは時としてより複雑で冗長なコードになる傾向があります。こういった些細な違い(些細と言えるほど小さな違いではないとも思いますが)の連続が大きな差を作りますのでコードは常にスッキリさせるよう配慮してください。
なおforEachメソッドは次の様な記述ルールが存在します。
コレクション名.forEach(引数 -> 繰り返し行う処理(引数));
実際に記述してみる
それでは実際にコードを記述してみましょう。
import java.util.*; public class Main { public static void main(String[] args) throws Exception { List list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); // forEach+ラムダ式 System.out.println("forEach+ラムダ式の場合"); list.forEach(s -> System.out.println(s)); // 拡張for文 System.out.println("拡張for文の場合"); for (String lst : list) { System.out.println(lst); } // 従来のfor文 System.out.println("従来のfor文の場合"); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } } }
実行結果
forEach+ラムダ式の場合 a b c 拡張for文の場合 a b c 従来のfor文の場合 a b c
このコードではリストの中身を全て順番に表示させています。
forEach+ラムダ式、拡張for文、従来のfor文の3つのメソッドを記述しています。動作は全て同一の動作ですが記述量が最も少なくスッキリして見えるのはforEachです。
色々な使い方
上の例ではArrayList(可変)でforEachメソッドを使ったコード記述の説明をしましたが、配列でforEachを使う場合には同じくJava 8の新機能であるStream APIを利用する必要が有ります。
Stream API
Stream APIを利用には次の様な記述ルールが存在します。
Arrays.stream(配列の変数名).forEach(引数 -> 繰り返し行う処理(引数));
次に実際のコードで動作を確認してみましょう。
import java.util.*; public class Main { public static void main(String[] args) throws Exception { String[] arr = {"a", "b", "c"}; Arrays.stream(arr).forEach(s -> System.out.println(s)); } }
実行結果
a b c
配列を全て取り出すことが出来ましたね。
配列とリストでは記述方法が若干異なります。配列利用時にStream APIを使用しないままコードを記述してしまうとコンパイルエラーになるので注意してください。
メソッド参照
メソッド参照もラムダ式、forEach、Stream APIなどと一緒にJava 8で追加された機能です。メソッド参照を利用すればラムダ式を省略することが出来ます。それでは早速コードを見てみましょう。
import java.util.*; public class Main { public static void main(String[] args) throws Exception { List list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.forEach(System.out::println); } }
実行結果
a b c
ラムダ式では”s -> System.out.println(s)”と記述している部分を”System.out::println”に変更していますが、実行結果はラムダ式を使った場合と同じになっているのが分かります。
このようにメソッド参照を使うことで更にスッキリとしたコードを記述することが出来ます。
まとめ
今回の記事ではJava 8で追加された機能である”forEach”についてカンタンではありますが説明させていただきました。
ラムダ式など聞きなれない言葉がいくつか出てきたとは思いますが、forEach+ラムダ式を利用することで今まで煩雑になりがちだった式を簡潔に記述することが出来ますので是非習得していただきたいと思います。
また拡張for文との違いについても簡単ではありますが例を出して説明していますので、もし違いを忘れてしまったと言うような方は、再度本記事を読んでいただければ幸いです。