2014年3月20日木曜日

古い FunctionalJava のラムダサンプルを Java 8で書き換えてみた

Javaプログラマなら知ってる FunctionalJavaっていう関数型プログラミングのライブラリが、けっこう昔からある。

このサンプルページに、それが書かれた当時、近々サポートされるであろうと想定されていた Java 7 closures を用いて書かれたものがある。

ただし、そのサンプルコード自体だいぶ古くて、今となっては文法も違っていたりするので、先日実際にリリースされた JDK8ではコンパイルできない。

というわけで、Java 8 を使ってちょっと書きなおしてみる。

まずオリジナルはこれ。
import fj.data.Array;
import static fj.data.Array.array;
import static fj.data.List.fromString;
import static java.lang.Character.isLowerCase;

public final class Array_exists {
  public static void main(final String[] args) {
    final Array<String> a = array("Hello", "There", "what", "DAY", "iS", "iT");
    final boolean b = a.exists({String s => fromString(s).forall({char c => isLowerCase(c)})});
    System.out.println(b); // true ("what" provides the only example; try removing it)
  }
}
で、書きなおしたやつがこれ。
import static java.lang.Character.isLowerCase;
import java.util.stream.Stream;

public final class Array_exists {
  public static void main(final String[] args) {
    final Stream<String> a = Stream.of("Hello", "There", "what", "DAY", "iS", "iT");
    final boolean b = a.anyMatch(s -> s.chars().allMatch(n -> isLowerCase((char)n)));
    System.out.println(b); // true ("what" provides the only example; try removing it)
  }
}
ラムダ式の部分だけじゃなく、fj.data パッケージ以下の Array や List も、Java8 標準APIで置き換えた(というか、そうせざるを得なかった)。

なんか chars() が IntStream を返してくるのがちょっと嫌な感じだけど、ここで議論されている。

(あと Java 8と直接関係あるわけではないが、当然ながら Stream.of() は static インポートすべきじゃないだろう。Stream of A, B and C という名詞句にするために敢えて前置詞を用いているはずなので。)

ちなみに Java7 以前のバージョンはこれ。
import fj.F;
import fj.data.Array;
import static fj.data.Array.array;
import static fj.data.List.fromString;
import static fj.function.Characters.isLowerCase;

public final class Array_exists {
  public static void main(final String[] args) {
    final Array<String> a = array("Hello", "There", "what", "DAY", "iS", "iT");
    final boolean b = a.exists(new F<String, Boolean>() {
      public Boolean f(final String s) {
        return fromString(s).forall(isLowerCase);
      }
    });
    System.out.println(b); // true ("what" provides the only example; try removing it)
  }
}
少なくともこのサンプルに限って言えば、だいぶマシになった感じだ。

0 件のコメント:

コメントを投稿