あるListを Stream で処理する時に要素1つが更に List などを走査時に取得して
全体のList として処理することを考える。
簡単なサンプルとして、String の split でどう書くかを確認しておくのが良いだろう。
List<String> list = List.of("1,2,3", "4,5,6", "7,8,9"); List<String> slist = list.stream().map(e->sampleList(e)) .flatMap(e->e.stream()) .collect(Collectors.toList());
public static List<String> sampleList(String str){ return Arrays.stream(str.split(",")).collect(Collectors.toList()); }
これなら、slist は、
[1, 2, 3, 4, 5, 6, 7, 8, 9]
となる。
Java8 までなら、map と flatMap でこのようにすれば良いだろう。
Java16 からの mapMulti は、
mapMulti - Oboe吹きプログラマの黙示録
では、汎用的なネストの例を書いていたが、この1階層のネストしかないものなら、
private void expandList(Object e, Consumer<Object> c) { for (String ie : sampleList(e.toString())) { c.accept(ie); } }
を用意して
List<String> slist = list.stream().mapMulti((a, b)->expandList(a, b)) .map(e->e.toString()).collect(Collectors.toList());
と mapMulti を使うことである。
これを実行するクラス名が ”Sample” として、static メソッドにして
メソッド参照にしたければ、、
public class Sample { public void exec() { List<String> list = List.of("1,2,3", "4,5,6", "7,8,9"); List<String> slist = list.stream().mapMulti(Sample::expandList) .map(e->e.toString()).collect(Collectors.toList()); } public static List<String> sampleList(String str){ return Arrays.stream(str.split(",")).collect(Collectors.toList()); } private static void expandList(Object e, Consumer<Object> c) { for(String ie : sampleList(e.toString())){ c.accept(ie); } } }
つまり、Java15 以前は、map と flatMap でごりごり書くしかないけど
Java16 からは、mapMulti で再帰 BiConsumer もしくは1回実行で
書けるということだ。