在日常开发中,我们经常会使用
Stream
来处理集合的操作。
其中,map
是我们经常用到的api
方法,同时呢,Stream
也给我们提供了flatmap
的方法。
这时候很多小伙伴就会搞不懂,这map
和flatmap
的区别在哪? 今天,我们就用简单易懂的方式,来搞懂两者的不同。
首先是map,这个相信大家都没啥疑问,我就用一张图来标识。
你可以把
map
看成是一个转换器,传入一个对象,然后它会吐给你新的对象。
现在到了flatmap
,为了更好的理解,我们先来一段代码对比下map
和flatmap
。
首先是map
,我们一般这样写。
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1,2,3,4,5,6);
//map的方式
List<Integer> collect1 = list.stream()
.map(t -> {
return t+1;
})
.collect(Collectors.toList());
}
其次是`flatmap`,我们如果也照着`map`的写法,会发现编译报错!
这个报错是,flatmap
的参数结构,需要返回Stream<? extends R>
类型,而我们这里直接返回了R!
可以看出
flatmap
和map
的参数差别在于,一个传入实体返回实体,另一个是传入实体返回的却是Stream流,那既然是流,那么最好返回值本身是一个Stream,或者能被转换成Stream的对象!
既然这样,那我们就手写一个例子,看看这样调用会得到什么样的结果呢。
public static void main(String[] args) {
List<Integer> list1 = Arrays.asList(1,2,3,4,5,6);
List<Integer> list2 = Arrays.asList(1,2,3,4,5,6);
List<List<Integer>> list = new ArrayList<>();
list.add(list1);
list.add(list2);
List<Integer> collect = list.stream()
.flatMap(t -> {
return t.stream().map(a -> a + 2);
})
.collect(Collectors.toList());
System.out.println(collect);
}
//运行结果 -------- [3, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7, 8]
你可以这么看,flatmap方法,就是把外层的嵌套集合,根据入参中的Stream结构,重新生成一个新的集合!
在这里,因为外层是一个List
包List
,所以入参的t
就是List<Integer>
, 所以 t.stream().map(a -> a + 2)
返回的 Stream
类型是Stream<Integer>
类型,
因此他调用的结果,必然是个Interge
集合而不是List<Integer>
。
弄懂了这点,你就知道了,flatmap的作用 —— 把嵌套集合,按照子集合的形式,统一放入到新的一个集合中去,这就叫结果展平!
例如,一个年级的学生,按照班级为单位,如今年段长想统计该年段所有的学生信息,一个flatmap就能轻松搞定,无需再for循环取遍历获取了~