【実践!Java】Stream APIをちゃんと理解する


■ Stream APIとは

Stream APIは、Listや配列を簡単に操作することができるイテレーションの拡張API。
例えば、for文でListから条件に合う値を取得する処理などはStream APIを使うことでよりシンプルに書くことができる。

大きく分けて以下の3つの操作を行う。
➀ Streamを生成

➁ 中間処理(省いてもOK)

➂ 終端処理

■ Stream生成

配列からストリーム生成

Arrays.stream(配列のdata)

listからストリーム生成

list.stream()

mapからストリーム生成

map.entrySet().stream()

■ 終端処理

生成したストリームを集計し、結果を返す処理。
簡単な処理であれば中間処理を省いて終端処理だけで実装できるため、先に紹介。

代表的なメソッド

メソッド 概要
anyMatch() 少なくとも一つの要素でtrueとなるか
allMatch() 全ての要素でtrueとなるか
nonMatch() 全ての要素でfalseとなるか
forEach() 全ての要素に関数を適用する
count() 要素数を返す
max() 最大値を返す
min() 最小値を返す
findFirst() 先頭の値を返す
findAny() 任意の値を返す
collect() リストとして取り出す

使い方

anyMatchを使って、Listの中に特定の文字列が含まれているかを判定。

// List作成
List<String> sampleList = Arrays.asList("hoge", "fuga", "piyo");

// anyMatchで終端処理
boolean flg = sampleList.stream().anyMatch(list -> list.equals("hoge"));

// true が出力される
System.out.println(flg);

■ 中間処理

中間処理を使うことで、ストリームに対してより複雑な処理を行うことができる。

代表的なメソッド

メソッド 概要
limit() ループさせる要素をn個までに制限
skip() ループさせる要素を先頭からn個skip
filter() filterで処理した結果trueの要素を返す
distinct() 重複する要素を排除して返す
sorted() 並び変えたストリームを返す
map() mapの要素を取得する

使い方

未成年の男の名前をListで取得する

List<String> youngMen  = men.stream()
  .filter(y -> y.age < 20)        // 20未満の男のみにする
  .map(y -> y.name)               // 名前を取得
  .collect(Collectors.toList());  // リストにして返す

(おまけ)はまったポイント

ラムダ式内でラムダ式外にある変数を書き換えることはできない。
Stream生成前に作成した変数をStream処理で使用しようとしたらエラーが出ました、、、
(finalな変数であれば問題ない)
Stream APIを使うなら、ラムダ式も理解しておくべき。