java.util.stream のソースを読んでみる filter 編
stream については、package java.util.stream; の JavaDoc には以下のように書かれています。
* A sequence of elements supporting sequential and parallel aggregate * operations.
並んでいる要素に対して、直列または並列処理をサポートするみたいなイメージでしょうか。
そもそも、Java8 ではなぜ List から stream() を使って Stream に変換が出来るのだろう?
> Collection インタフェースに stream() が用意されていて、List ではそれを継承しているようです。
https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html
では、filter の JavaDoc を見てみます。
/** * Returns a stream consisting of the elements of this stream that match * the given predicate. * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. * * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>, * <a href="package-summary.html#Statelessness">stateless</a> * predicate to apply to each element to determine if it * should be included * @return the new stream */ Stream<T> filter(Predicate<? super T> predicate);
うーん。Predicate ですか。
では、Predicate の JavaDoc を見てみます。
/** * Represents a predicate (boolean-valued function) of one argument. * * <p>This is a <a href="package-summary.html">functional interface</a> * whose functional method is {@link #test(Object)}. * * @param <T> the type of the input to the predicate * * @since 1.8 */
これだけでは、ピンと来なかったですが、用意されているメソッドを見てみると、test(T t) というものがあります。
/** * Evaluates this predicate on the given argument. * * @param t the input argument * @return {@code true} if the input argument matches the predicate, * otherwise {@code false} */ boolean test(T t);
与えられた引数が条件(直訳だと述語?)に一致した場合は、true 一致しない場合は false を返します。
interface Predicate
つまり、Stream
与えたデータ型 T が boolean に変換されるとも捉えられるので、
Stream
こんな感じに変換(おおざっぱに)捉えることにします。
例として、
List<String> before = Arrays.asList("a", "b", "c"); List<String> after = before.stream().filter(e -> e.equals("b")).collect(Collectors.toList()); after.forEach(System.out::println); // b
filter(T -> boolean) と filter(e -> e.equals("b")) のような関係にこじつけられます。