示例
有时候我们会遇到:如何将Map<String, List<String>> map
的所有值合并为一个List<String>
对象,这时候就可以使用flatMap()
。
示例如下:
public static void flatMapDemo() {
Map<String, List<String>> map = new HashMap<>();
// 生成3个键值对,每个值是包含5个元素的list的map
IntStream.range(0, 3).forEach(i -> {
List<String> list = new ArrayList<>();
IntStream.range(0, 5).forEach(j -> list.add("val-" + j));
map.put("key-" + i, list);
});
System.out.println("map: " + map);
// 收集map中所有值,将其转为list
List<String> values = map.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
System.out.println("list: " + values);
}
输出为:
map: {key-1=[val-0, val-1, val-2, val-3, val-4], key-0=[val-0, val-1, val-2, val-3, val-4], key-2=[val-0, val-1, val-2, val-3, val-4]}
list: [val-0, val-1, val-2, val-3, val-4, val-0, val-1, val-2, val-3, val-4, val-0, val-1, val-2, val-3, val-4]
Stream.flatMap()方法
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
官网解释:
返回一个流,包含将此流中的每个元素替换为通过给定函数映射应用于每个元素而生成的映射流的内容
上述解释可能比较难理解,这里更通俗的解释是,flatMap对流中的元素使用映射函数后再平铺一个流进行返回。所以可以理解上述用例代码,map.values().stream()
返回的是一个所有元素都为List<String>
的流,再使用flatMap(Collection::stream)
,将每个List<String>
中的所有元素变为一个流,这样原本由3个List,每个List5个元素的流, 变成了15个String元素的流,然后再合并可以转为一个List。
map()与flatMap()的区别
区别
map()
返回一个流,包含给定函数应用在流中每一个元素后的结果
flatMap()
返回一个流,包含将此流中的每个元素替换为通过给定函数映射应用于每个元素而生成的映射流的内容
使用场景:
map()
对流中的每个元素进行简单的转换,mapper函数返回的是Object对象flatMap()
对流进行平铺后合并,mapper函数返回的是一个stream对象