Java 基礎からマスターまで — 第6回
Lambda、Stream、Optionalでデータフローを作成する
本ブログ作成文は、講義を目指して製作されました。 また、作成された文章の情報も間違っている可能性がありますので、ご注意ください。
コレクションから条件に合った値を均等に変換して合算するコードはよく登場する。 LambdaとStreamは、データがどのステップを通過するかを計算の流れとして表します。
ラムダ
Predicate<Monster> isAlive = monster -> monster.getHealth() > 0;
Function<Monster, String> getName = Monster::getName;
Lambdaはアクションを値のように渡すことができます。 メソッド参照は、すでに存在するメソッドを同じ関数形式で使用するときに簡潔です。
ストリームパイプライン
List<String> targetNames = monsters.stream()
.filter(Monster::isAlive)
.sorted(Comparator.comparingInt(Monster::getHealth))
.limit(3)
.map(Monster::getName)
.toList();
生きているモンスターを体力順に並べて三つの名前を得る流れだ。 中間演算は通常、最終演算が呼び出されたときに実行されます。
ストリームを一度消費すると、同じストリームを再利用できません。 元のコレクションを繰り返しクエリするか、結果をリストとして保存する必要があります。
Optional
Optional<Item> item = repository.find(10);
String name = item
.map(Item::getName)
.orElse("Unknown");
Optionalは、値があってもなくてもよいという事実を戻り値型に表示します。 get()をすぐに呼び出すと、なし処理が再び失われるため、orElse、map、ifPresentなどの操作が使用されます。
オプションは、すべてのフィールドとパラメータへの書き込みよりも戻り値の不在を表すために使用されることがよくあります。
パフォーマンスと読みやすさ
ストリームは常に反復ステートメントよりも高速ではなく、小さな演算オブジェクトと結果のリストを作成できます。 読みやすい流れから始めた後、実際の測定で問題となる繰り返しパスだけを単純ループに変えるほうが良い。
LambdaとStreamの目的は、コードを最も短くすることではありません。 フィルタ、変換、並べ替えというデータ処理ステップを副作用なく読み取ることができるようにするのだ。