簡単な要件を満たすコードを書くにあたって、Lambda を使わないケースと使うケースを比較してみます。
以下のような数字のリストを用意し、100以上の分だけ2倍したものを合算する処理を考えてみます。
仕様:100以上の分だけ2倍したものを合算する
final List<Integer> numbers = Arrays.asList(50, 100, 10, 400, 120, 30, 220);
Lambda を使用しないケース
たとえば、リスト内の値を一つずつチェックし、もし100以上であればその数値を2倍し、total に加算するという流れが考えられます。
これ位の計算であれば、シンプルで分かりやすく大きな問題はないと思われます。
ただ、仕様(100以上の分だけ2倍したものを合算する)に対して、それを実現する一つの方法として ”数字を一つずつチェックする” というエンジニアのアイデアがそこに挟まれるため、やや誤解を与えやすいコードになる可能性があります。
int total = 0;
for (Integer number : numbers) {
if (number >= 100) {
total += number * 2;
}
}
System.out.println("Total is " + total);
Lambda を使用するケース
トータルのコード量としては上記とさほど変わっていません。
ただ、コードから見える処理の流れの読み方が変わってきます。
”リストから100以上の数値をフィルターで取り出し、2倍し、それらを合計する”となります。
ループで一つずつチェックするようなコードは書いていません。
まるで仕様(100以上の分だけ2倍したものを合算する)をそのまま記述しているような形で表現ができています。
全てのケースでそれが当てはまるわけではないと思いますが、要求仕様に対してより誤解の少ないコードがこの例では書けていると思います。
int total = 0;
total = numbers.stream()
.filter(num -> num >= 100)
.map(num -> num * 2)
.reduce(0, (base, value) -> base + value);
System.out.println("Total is " + total);