StreamAPIについて調べてみた peek編 その1
【前提条件】
【概要】
今回はpeekについて調べてみました。
peekはStream内にある要素に対して
追加的に処理を行い他時に使用するメソッドです。
【peekメソッド】
[サンプルソース]
public static void main(final String[] args) { final List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); final int sumValue = list.stream() .peek(v -> System.out.println("debug! [" + v + "]")) .collect(Collectors.summingInt(v -> v)); System.out.println(sumValue); }
peekメソッドはConsumerオブジェクトをパラメータとして受け取ります。
Consumerなのでパラメータを受け取り、戻り値がない関数オブジェクトになります。
サンプルではStream内の要素を出力させています。
[出力結果]
debug! [1] debug! [2] debug! [3] 6
【考察】
peekメソッドはConsumer関数なので、
副作用を伴う処理を行う場合に使うものです。
[サンプルソース]
public static void executeStringBuilderList() { final List<StringBuilder> list = new ArrayList<>(); list.add(new StringBuilder("one")); list.add(new StringBuilder("two")); list.add(new StringBuilder("three")); list.stream() .peek(v -> v.append("-value")) .forEach(v -> System.out.println(v.toString())); }
副作用を伴う処理の例です。
ListにStringBuilderを入れているて、peek内で値を書き換えています。
(普通はこのようなコードは書かないと思いますがサンプルなので)
[出力結果]
one-value two-value three-value
「mapとかでも同じことできるじゃん」と思うかもしれません。
確かにmapでも同じことはできるのですが、
Stream内の要素を別の型に変えることが主な役割なので
その処理内で副作用があるのは好ましいとは思いません。
「mapなのに中の値が書き換わってる」と言いながらバグ調査することになると思います。
getterなのに値が書き換わるとかそういうのと同じかなと思います。
Streamの処理内で副作用を伴う処理を実行したい場合は
明示的にpeekメソッドで実行したほうが読みやすくなると思います。