先来个总结:
map是对一级元素进行操作,flatmap是对二级元素操作。
map自动返回stream对象,flatmap处理后的元素依然要是stream对象(可以用stream.of,Arrays.stream将元素转为stream对象)。
打个比方,有一个二维数组a[2][3],通过map每次操作的都是一个一维数组,如a[0]和a[1],执行完后就各自返回一个处理后的一维数组,这样a[2][3]经过map操作后就会返回两个一维的数组,然后汇集成一个stream后返回。
而flatmap每次操作后就是单个元素,比如a[0][0],a[0][1],所有元素执行完后再汇集起来变成一个stream。
详细经过:
定义一个字符串数组 ss:
String[] ss = {
"hello welcome",
"world hello",
"hello world",
"hello world welcome"
};
通过Stream.of获取一个stream
Stream<String>testStream= Stream.of(ss);
这stream其实是一个字符串的数组转换来的,我们通过将整个流的每个元素进行字符串拆分(split),再输出拆分后的字符串
通过map进行字符串分割操作后的ss变成了 一个二维数组。
testStream.map(str-> str.split(" "))
.forEach(strStream-> System.out.println(strStream));
控制台输出:
[Ljava.lang.String;@5a42bbf4
[Ljava.lang.String;@270421f5
[Ljava.lang.String;@52d455b8
[Ljava.lang.String;@4f4a7090
我们可以看到经过map后,原本的stream是被分成了四个string数组对象,借助Arrays.toString转换成字符串后查看:
testStream.map(str-> Arrays.stream(str.split(" ")))
.forEach(strStream-> System.out.println(Arrays.toString(strStream.toArray())));
输出:
[hello, welcome]
[world, hello]
[hello, world]
[hello, world, welcome]
也就是说,之前的map的操作是对ss[i] (0 <=i <4) 分别进行处理,处理完后就返回一个数组对象,最后再变成一个stream,所以在stream的foreach遍历的时候,就有四个stream对象
而flatmap的操作则是深入到每一个元素,对每个ss[i]数组处理后,汇集成一个新的stream
testStream.flatMap(str-> Arrays.stream(str.split(" ")))
.forEach(strStream-> System.out.println(strStream));
注意flatmap与map上的用法区别,flatmap需要再加一个Arrays.stream,而map不用。
控制台输出:
hello
welcome
world
hello
hello
world
hello