-- / --
--
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

04 / 26
Sat

もう 4 月も終わりか…、 という感じの Ziphil です。

いつの間にか Java8 がリリースされていました。 どうやら、 ラムダ式が追加されたみたいで、 これは Rubyist である (だった?) 自分には嬉しい仕様です。 どんなのかというと、 こんなのです。

List list = Arrays.asList("foo", "bar", "baz", "hoge", "huga");
list.forEach((String s) -> {
  String data = "[" + s + "]: " + s.length();
  System.out.println(data); 
});

map とか filter とか reduce とかもちゃんとあります。 ただし、 この場合は一度コレクションを Stream オブジェクトに変換しないといけません。 これがちょっと面倒。

List list = Arrays.asList("foo", "bar", "baz", "hoge", "huga");
String result = list.stream().filter((String s) -> {
  return s.length() > 3;
}).map((String s) -> {
  return s.toUpperCase();
}).reduce((String s, String t) -> {
  return s + ", " + t;
}).get();
System.out.println(result);

ラムダ式では型推論が働いてくれるので、 引数の型は省略できます。 また、 ラムダ式を 1 行で書くばあいは return 文も不要です。 さらに、 引数が 1 つだけの場合は、 引数の前後のカッコも省略できます。 ・・・ということで、 上のプログラムは下のようにも書けます。

List list = Arrays.asList("foo", "bar", "baz", "hoge", "huga");
String result = list.stream().filter(s -> s.length() > 3).map(s -> s.toUpperCase()).reduce((s, t) -> s + ", " + t).get();
System.out.println(result);

Ruby を長いこと使ってきた私にとっては、 こう書けると非常に親近感がわきます。 Ruby だとこんな感じで、 似てますからね。

list = ["foo", "bar", "baz", "hoge", "huga"]
result = list.select{|s| s.length > 3}.map{|s| s.upcase}.reduce{|s, t| s + ", " + t}
puts result

さて、 この Java のラムダ式ですが、 実装はどうなっているかというと、 ただの匿名クラスです。 たとえば、 Stream#filter の引数の型は Predicate<T> です。 つまり、 Java がラムダ式を Predicate<T> を継承した匿名クラスに勝手に変換してくれるイメージです。 ちなみに、 Predicate<T> は T 型の引数をとり Boolean 型を返すラムダ式に相当します。

ということで、 今までラムダ式とかクロージャとか、 そういう類のものが使えないせいで、 for 文が嫌いな私は Ruby とか Scala とか Groovy とか Kotlin とか Fantom とか Xtend とかに逃げてましたが、 その必要もほとんどなくなりましたね。

あ、 そうそう、 ラムダ式の変換先となる関数型インターフェースには、 引数の型や返り値の型などによって Supplier とか Consumer とか Prdicater とかいろいろあるんですが、 プリミティブ型専用に IntSupplier とか IntConsumer とかがあるんですよね。 それならプリミティブ型廃止すれば良いのに!

スポンサーサイト

comment ×0
コメント
管理者にだけ表示を許可する
 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。