Java8中map和flatmap的共同点和区别

在函数式语言中,函数作为一等公民,可以在任何地方定义,在函数内或函数外,可以作为函数的参数和返回值,可以对函数进行组合。由于命令式编程语言也可以通过类似函数指针的方式来实现高阶函数,函数式的最主要的好处主要是不可变性带来的。没有可变的状态,函数就是引用透明(Referential transparency)的和没有副作用(No Side Effect)。

任何一种函数式语言中,都有map函数与faltMap这两个函数,比如python虽然不是纯函数式语言,也有这两个函数。再比如在jdk1.8之后,也加入了Lambda表达式,自然也支持map函数。

一、map和faltMap的共同点和区别

1、共同点
  •  都是依赖FuncX(入参,返回值)进行转换(将一个类型依据程序逻辑转换成另一种类型,根据入参和返回值)
  •  都能在转换后直接被subscribe
2、区别
  • map返回的是结果集,flatmap返回的是包含结果集的Observable(返回结果不同)
  • map被订阅时每传递一个事件执行一次onNext方法,flatmap多用于多对多,一对多,再被转化为多个时,一般利用from/just进行一一分发,被订阅时将所有数据传递完毕汇总到一个Observable然后一一执行onNext方法(执行顺序不同)>>>>(如单纯用于一对一转换则和map相同)
  • map只能单一转换,单一只的是只能一对一进行转换,指一个对象可以转化为另一个对象但是不能转换成对象数组(map返回结果集不能直接使用from/just再次进行事件分发,一旦转换成对象数组的话,再处理集合/数组的结果时需要利用for一一遍历取出,而使用RxJava就是为了剔除这样的嵌套结构,使得整体的逻辑性更强。)
  • flatmap既可以单一转换也可以一对多/多对多转换,flatmap要求返回Observable,因此可以再内部进行from/just的再次事件分发,一一取出单一对象(转换对象的能力不同)

二、实例

假如我们有这样一个需求给定单词列表[“Hello”,”World”],你想要返回列表[“H”,”e”,”l”, “o”,”W”,”r”,”d”],
对于这样的需求,我们可能想到的第一个版本可能是这样子的:

words.stream()
.map(word -> word.split(""))
.distinct()
.collect(toList());

这个方法的问题在于,传递给map方法的Lambda为每个单词返回了一个String[](String
列表)。因此, map 返回的流实际上是Stream 类型的。你真正想要的是用
Stream来表示一个字符流。因此,这是行不通的。

以下是我对这个问题的解法和分步写法,希望能对你有帮助:

String ss = "Hello";
String[] aa = ss.split("");
String[] bb = {"H", "e", "l", "l", "o"};
String[] strings = {"Hello", "World"};

//Arrays.stream接收一个数组返回一个流
List> streamList = Arrays.asList(strings).stream().
                 map(str -> str.split("")).
                 map(str -> Arrays.stream(str)).
                 collect(Collectors.toList());
 
//分步写(map)
Stream stream = Arrays.asList(strings).stream().
                 map(str -> str.split(""));
 
Stream> streamStream = stream.map(strings1 -> Arrays.stream(strings1));
List> streamList1 = streamStream.collect(Collectors.toList());
 
List stringList = Arrays.asList(strings).stream().
                 map(str -> str.split("")).
                 flatMap(str -> Arrays.stream(str))
                 .collect(Collectors.toList());

//分步写(流只能消费一次)(flatMap)
Stream stream1 = Arrays.asList(strings).stream().
                 map(str -> str.split(""));
 
Stream stringStream = stream1.flatMap(strings1 -> Arrays.stream(strings1));
 
List stringList1 = stringStream.collect(Collectors.toList());

对flatMap的说明:这个在这里的主要作用是对流进行扁平化

三、最后总结

现在简单说说scala中这两个函数的用法。有一种观点认为将map和flatMap说成Scala函数机制的核心都不为过分,其实是有一定道理的。因为实际中我们使用最多的场景就是对数据进行map操作或者flatMap操作。

map函数的用法,顾名思义,将一个函数传入map中,然后利用传入的这个函数,将集合中的每个元素处理,并将处理后的结果返回。而flatMap与map唯一不一样的地方就是传入的函数在处理完后返回值必须是List,其实这也不难理解,既然是flatMap,那除了map以外必然还有flat的操作,所以需要返回值是List才能执行flat这一步。

原文:https://blog.csdn.net/zhuwukai/article/details/82888316


已发布

分类

,

来自

标签:

评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注