2014年6月8日日曜日

Java8のlambda式について

Java8が公開されてそれなりに時間が経ちましたが、さすがにそろそろLambda式に慣れないとまずいということでメモとして残していきます。

Java7までの書き方から始まり、徐々にラムダ式の簡略記法に変換していく感じでまとめています。
go1メソッド→go4メソッドまで順序だてる感じで簡略化していきます。
簡略化の仕方に関しては各メソッドにコメントとして記載しているのでそちらを参照してもらえるとわかりやすいかと思います。

package lambda1;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.UnaryOperator;

public class Main {

 private static final List list = Arrays.asList("a", "b", "c", "d",
   "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q",
   "r", "s", "t", "u", "v", "w", "x", "y", "z");

 public static void main(final String[] args) {
  Main m = new Main();
  m.go1();
  m.go2();
  m.go3();
  m.go4();
 }

 /**
  * Java8以前の記述方法。
  * この記述を徐々に簡略化していきます。
  */
 public void go1() {
  System.out.println("go1");
  final List l = new ArrayList(list);
  System.out.println(l.toString());
  l.replaceAll(new UnaryOperator() {

   @Override
   public String apply(String str) {
    return "==" + str;
   }

  });
  System.out.println(l.toString());
 }

 /**
  * replaceAllの引数のUnaryOperatorインタフェースは
  * @FunctionalInterfaceのアノテーションが付いているので、
  * ラムダ式で記述を置き換えられる。
  */
 public void go2() {
  System.out.println("go2");
  final List l = new ArrayList(list);
  System.out.println(l.toString());
  l.replaceAll((String t) -> {
   return "==" + t;
  });
  System.out.println(l.toString());
 }

 /**
  * 処理が1行の場合は{}で囲う必要がないので削除。
  * さらにreturnも1行の場合は削除できるので削除。
  */
 public void go3() {
  System.out.println("go3");
  final List l = new ArrayList(list);
  System.out.println(l.toString());
  l.replaceAll((String t) -> "==" + t);
  System.out.println(l.toString());
 }

 /**
  * 型は推論してくれるし、かつ引数が1個なのでカッコも不要。
  */
 public void go4() {
  System.out.println("go4");
  final List l = new ArrayList(list);
  System.out.println(l.toString());
  l.replaceAll(t -> "==" + t);
  System.out.println(l.toString());
 }
}


しかし、便利ですね。
最初はPHPみたいな矢印マークでとっつきにくかったですが、こうやって徐々に簡略化していくと色々とわかりやすく学べました。
これなら、自分で関数インタフェース(@FunctionalInterface)を利用して、便利に色々と作れる気がしてきました。