java7 flatmap_Java流中的map算子和flatMap算子的区别

map算子和flatMap算子

map和flatMap都是映射(转换),那么他们之间究竟有什么区别呢?

1.我们先简单了解下map算子:

@org.junit.Test

public void test1(){

List words = Arrays.asList("hello","world");

words.stream()

.map(String::length) //使用了方法引用,将String类型转换为int类型

.forEach(System.out::println);

}

//输出:5 5

map是流的中间操作,Streammap(Function super T, ? extends R> mapper)

传入一个Function函数式接口,返回一个流。关于函数式接口和lambda表达式可以看我之前的随笔。

2.再看个例子,来简单了解下两者间的区别,先着重思考一下下面的案例用map会有什么问题?

​需求:传入一个集合 list = Arrays.asList("hello","Hello")

​要求:输出:h,e,l,o,H (单词里面的每一个字母去重 ,并且进行打印)

@org.junit.Test

public void test2(){ //错误演示

List list = Arrays.asList("hello","Hello");//h,e,l,o,H

list.stream()

.map(m->m.split(""))

.distinct()

.collect(toList())

.stream()

.forEach(System.out::println);

}

那么输出结果符合我们的需求吗?

//输出结果:这俩行是个什么鬼?

[Ljava.lang.String;@51e2adc7

[Ljava.lang.String;@1a8a8f7c

这显然不符合我们的要求,那究竟是哪里出错了呢?我们一步一步分析一下:

1.StreambaseRDD = list.stream(); 将集合转换为流

2.Stream mapRDD= baseRDD.map(w->w.split("")); 调用map算子,转换

3.Stream distinctRDD= mapRDD.distinct(); 调用distinct算子,去重

4.List collectRDD = distinctRDD.collect(toList());流转换为集合,最后输出

我们一步一步分析下来,看起来是不是还是没问题呢?接下来让我们再改写一下:

@org.junit.Test

public void test3(){

List words = Arrays.asList("hello","Hello");//h,e,l,o,H

Stream mapRDD = words.stream()

.map(word->word.split(""));

mapRDD.map(Arrays::stream)

.distinct()

.collect(toList())

.stream()

.forEach(System.out::println);

}

//输出:这又是个什么鬼???是不是越来越迷糊了,不要着急

java.util.stream.ReferencePipeline$Head@2353b3e6

java.util.stream.ReferencePipeline$Head@631330c

再来一步一步分析一下:

Stream map1RDD = words.stream().map(word->word.split(""));转换

Stream map2RDD = map1RDD.map(d->Arrays.stream(d));

Stream distinctRDD = map2RDD.distinct();

List finalList = distinctRDD.collect(toList());

这里我们需要注意的是:map转化(输入一个类型,返回另外一个类型)

​输入类型的值(值的类型是上一个数据集的泛型)

​输出数据的类型会作为下一个数据集的泛型

还是不理解?没关系,等会我们通过图来深刻理解一下。

那flatMap算子呢?

@org.junit.Test

public void test4(){

List words = Arrays.asList("hello","Hello");//h,e,l,o,H

words.stream()

.map(word->word.split(""))

.flatMap(d->{

Stream stream = Arrays.stream(d);

return Arrays.stream(d);

})

.distinct()

.forEach(System.out::println);

}

//输出

heloH

居然成功实现了需求,这两者究竟有什么区别呢?我们通过图画来更加生动形象的了解下(画图不易,值得一赞)

5a04fb2c081a33059b3a90a0b3c1dc17.png

对比一下flatMap算子:

f0dbf80df63d0b4f3c2e811ed8a927e9.png

这样就一目了然了!!!

总结一下:

​ map算子:map返回值类型就是新的数据集的泛型

​ flatMap算子: flatMap算子返回类型就是新的数据集的类型

最后再看个案例:

​需求:输入:【1,2,3】【3,4】

​ 输出:【(1,3),(1,4),(2,3),(2,4),(3,3),(3,4)】

@org.junit.Test

public void test7(){

//集合(.stream())

List number1 = Arrays.asList(1,2,3);

List number2 = Arrays.asList(4,5);

/**

* 倒着推理一下 :

* 最终的结果(终端): List

* 终端操作的上一个操作:Stream

*

*/

List pairs = number1.stream()

.flatMap(i->{

// Stream stream =

// number2.stream().map(j->new int[]{i,j});

return number2.stream().map(j->new int[]{i,j});

})

.collect(toList());

Stream intArrayRDD = pairs.stream();

intArrayRDD.forEach(arr->{

for(int i : arr){

System.out.print(i+" ");

}

System.out.println();

});

}//OK

至此,map算子和flatMap算子就介绍完毕了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值