Java の Stream に入門した

Steram 自体はずいぶん前に出た機能だが、慣れないうちに Java をほとんど書かなくなってしまった。 久しぶりに Java のコードを読むようになったらちょこちょこ Stream が出てきて読むのが大変だったので、少し触ってみた。

JavaScript / TypeScript で似たことができるので、同様のコードを書いて並べてみる。

map、filter、anyMatch (some)

JS/TS とあまり変わらない。 stream() や collect() の見た目に慣れられれば良さそう。

List<String> list = Arrays.asList("hoge", "fuga", "piyo", "mofu");

// list.map((s) => s + s);
List<String> result1 = list.stream()
        .map(s -> s + s)
        .collect(Collectors.toList());
System.out.println(result1);
// [hogehoge, fugafuga, piyopiyo, mofumofu]

// list.filter((s) => s == "piyo")
List<String> result2 = list.stream()
        .filter(s -> s.equals("piyo"))
        .collect(Collectors.toList());
System.out.println(result2);
// [piyo]

// list.some((s) => s == "piyo")
boolean result3 = list.stream()
        .anyMatch(s -> s.equals("piyo"));
System.out.println(result3);
// true

Function、Predicate

Predicate 型が Function 型とは別に存在していることに面食らった。 「1つの引数の述語(boolean値関数)を表します」ということで and(), or(), negate() がある。

// func = (s) => s.length;
// result4 = list.map(func);
Function<String, Integer> function = s -> s.length();
List<Integer> result4 = list.stream()
        .map(function)
        .collect(Collectors.toList());
System.out.println(result4);
// [4, 4, 4, 4]

// predicate1 = (s) => s == "piyo";
// result5 = list.every(predicate1);
Predicate<String> predicate1 = s -> s.equals("piyo");
boolean result5 = list.stream()
        .allMatch(predicate1);
System.out.println(result5);
// false

// predicate2 = (s) => s == "mofu";
// predicate3 = (s) => predicate1(s) || predicate2(s);
// result6 = list.map(predicate3);
Predicate<String> predicate2 = s -> s.equals("mofu");
Predicate<String> predicate3 = predicate1.or(predicate2);
List<Boolean> result6 = list.stream()
        .map(s -> predicate3.test(s))
        .collect(Collectors.toList());
System.out.println(result6);
// [false, false, true, true]