PR

 Project Lambdaの3回目となる今回は、ストリームの中間操作と終端操作を紹介していきます。

 その前に、簡単に前回のおさらい。

 Stream APIは内部イテレータを実現するためのAPIで、イテレーションの処理にラムダ式を使用します。また、その特徴としてイテレーションの結果を集約して結果を返すことができます。

 ストリームを使った処理はメソッドチェーンで記述し、メソッドチェーンの途中の処理を中間操作、最後の処理を終端操作と呼びます。

 ストリームにはさまざまな中間操作、終端操作がありますが、今回扱うのは表1に示した4メソッドだけです。

表1●代表的なストリームのメソッド
操作メソッド名説明
中間操作filter条件に合致した要素を残すフィルタリング処理
map要素を他の値に変換するマッピング処理
flatMapmapの一種で、マッピングと入れ子になったストリームを平坦化する処理
終端操作collect汎用的に使用できる集約処理

 この4つのメソッドだけと思われる人もいるかもしれませんが、これだけで多くの処理を記述することが可能です。ストリームを使う上で必要最低限のメソッドといっても過言ではありません。また、これらのメソッドの使い方が分かれば、他のメソッドの使い方も容易に推測できるようになるはずです。

中間操作

filterメソッド

 filterメソッドはストリームでイテレートする要素の中から、条件に合致する要素を残して新たなストリームを作成するメソッドです。条件の記述には、もちろんラムダ式を使用します。

 引数の型は関数型インタフェースのjava.util.function.Predicateインタフェースです。Predicateインタフェースは引数がジェネリクスの型パラメータ、返り値がboolean型のtestメソッドを定義しています。つまり、イテレートされる要素がtestメソッドの引数となり、返り値がtrueの場合に要素を残します。

 例えば、整数のリストから偶数を残して、標準出力に出力するには次のように記述します。

リスト1●偶数だけを残すフィルタリング

int[] numbers = {0, 1, 2, 3, 4, 5, 6};
        
Arrays.stream(numbers)         // 配列からIntStreamオブジェクトを生成
      .filter(x -> x % 2 == 0) // 偶数のみを残すための条件式
      .forEach(x -> System.out.println(x));

 ここではint型の配列からストリームを生成するために、java.util.Arraysクラスのstreamメソッドを使用しています。int型の配列から生成しているため、IntStreamオブジェクトが生成されます。

 ストリームの生成に関しては前回解説しましたので、ご参照ください。

 赤字で示したfilterメソッドでフィルタリングを行っていきます。%演算子は除算の余りを求めます。ここでは、2で割った余りと0を比較しています。つまり、青字で示したラムダ式は偶数の場合、trueを返します。

 この結果、ストリームは[0, 2, 4, 6]となります。

 この処理を図示したのが、図1です。条件に合致する要素だけ取りだして、新たなストリームを生成します。

図1●filterメソッドの動作
図1●filterメソッドの動作