質問: new ArrayList<>(); // Parent, Child 生成... for (Parent p : parents) { for (Child c : p.getChildren()) { System.out.println(c); // c を使った処理 } } ``` 上記`for`文を、`Stream`を使用したものに置き換えたいと考えています。 自分が思いついたものとしては次の2パターンが有るのですが、実行結果はどちらも変わらないように思われました。 実際には途中の処理順やパフォーマンス等、何か差異があるでしょうか。 また、`Stream`の書き方としてより適切なのはどちら(あるいはどちらでもない)か、というのも知りたいです。 (バラせるところはバラしたほうが良い、つまりパターン1の方が良いのかな、と漠然と考えているのですが...) ``` // パターン1 parents.stream().map(Parent::getChildren).flatMap(List::stream) .forEach(System.out::println); // パターン2 parents.stream().flatMap(p -> p.getChildren().stream()) .forEach(System.out::println); ```
回答: > > 実際には途中の処理順やパフォーマンス等、何か差異があるでしょうか。 > > > * 逐次(sequential)ストリームとなっているため、両パターンとも処理順序は同一です。 * (有意差はないと予想しますが、)パフォーマンス比較は実環境にて計測してください。 > > Streamの書き方としてより適切なのはどちら(あるいはどちらでもない)か、というのも知りたいです。 > > > 正解のない問いだと思いますが、個人的には パターン2 の方が好ましいと考えます。 * パターン1: `.map(Parent::getChildren).flatMap(List::stream)` * パターン2: `.flatMap(p -> p.getChildren().stream())` 論理的には「子Listのflatten処理」でひとかたまりの操作ですから、パターン1のように外側ストリームのメソッドチェインで分断してしまうより、パターン2のように一度のflatMap操作で変換する方が意図をより直接的にコード化しているという考え方です。