Java中如何用Stream合并List<String>为单个List?求替代addAll的Collectors方法
当然有合适的方法啦!你遇到的问题是因为map()会把每个元素转换成另一个对象(这里是List<String>),所以收集后得到的是嵌套列表。要替代addAll的效果,你可以用下面两种更符合Stream函数式风格的方式:
方法一:使用flatMap()(最常用)
flatMap()的作用就是把每个元素对应的嵌套流“扁平化”成单个流。你只需要把getList()返回的List<String>转换成Stream<String>,flatMap()会自动把所有小流合并成一个包含所有元素的大流,最后再收集成列表:
List<String> resultList = listData.stream() .flatMap(str -> getList(str).stream()) .collect(Collectors.toList());
这个写法完全替代了你原来用forEach(resultList::addAll)的逻辑,而且不需要维护外部的可变集合,更符合Stream的设计理念。
方法二:使用Java 9+的Collectors.flatMapping()
如果你用的是Java 9及以上版本,还可以用Collectors.flatMapping(),它是在收集阶段完成扁平化操作,适合更复杂的收集场景(比如分组后再扁平化)。针对你的需求,写法如下:
List<String> resultList = listData.stream() .collect(Collectors.flatMapping( this::getList, Collectors.toList() ));
这里flatMapping()接收两个参数:第一个是把元素转换成嵌套集合的函数(就是你的getList()),第二个是用来收集所有元素的Collector(这里是toList())。
为什么之前的写法得到List<List<String>>?
简单说,map(this::getList)会把流中的每个String转换成List<String>,所以流的类型是Stream<List<String>>,用Collectors.toList()收集后自然就是List<List<String>>。而flatMap()和flatMapping()的核心就是把这些嵌套的列表“拆”开,把所有元素放到同一个层级里。
内容的提问来源于stack exchange,提问作者Manikandan Balasubramanian

