在Java 8中,Stream.map()和Stream.flatMap()方法之间有什么区别?


当前回答

对于Map,我们有一个元素列表和一个(函数,动作)f,这样:

[a,b,c] f(x) => [f(a),f(b),f(c)]

对于平面映射,我们有一个元素列表,我们有一个(function,action) f,我们希望结果是扁平的:

[[a,b],[c,d,e]] f(x) =>[f(a),f(b),f(c),f(d),f(e)]

其他回答

如果你熟悉c#也可以很好的类比。基本上c# Select类似于java map和c# SelectMany java flatMap。对于集合,同样适用于Kotlin。

传递给流的函数。Map必须返回一个对象。这意味着输入流中的每个对象都会导致输出流中的一个对象。

传递给流的函数。flatMap为每个对象返回一个流。这意味着该函数可以为每个输入对象返回任意数量的对象(包括none)。然后将结果流连接到一个输出流。

简单的答案。

映射操作可以生成流的流。前流<流<整数> >

flatMap操作只会产生流。前流<整数>

.map用于A -> B映射

Stream.of("dog", "cat")              // stream of 2 Strings
    .map(s -> s.length())            // stream of 2 Integers: [3, 3]

它将任意项A转换为任意项b


.flatMap用于A ->流< B>连接

Stream.of("dog", "cat")             // stream of 2 Strings
    .flatMapToInt(s -> s.chars())   // stream of 6 ints:      [d, o, g, c, a, t]

it——1将任何项A转换为Stream< B>,然后——2将所有流连接到一个(平面)流。Javadoc


注1:虽然后面的例子是一个原语流(IntStream),而不是一个对象流(stream),但它仍然说明了. flatmap的思想。

注意2:尽管有这个名字,String.chars()方法返回的是整数。所以实际的集合将是:[100,111,103,99,97,116] ,其中100是“d”的代码,111是“o”的代码,等等。同样,为了说明目的,它被表示为[d, o, g, c, a, t]。

如果您认为map()是一个迭代(一级for循环),那么flatmap()是一个两级迭代(类似于嵌套的for循环)。(输入每个迭代元素foo,然后执行foo. getbarlist()并再次迭代该barList)


Map():获取一个流,对每个元素做一些事情,收集每个进程的单个结果,输出另一个流。“做一些函数”的定义是隐含的。如果任何元素的处理结果为null,则使用null来组成最终流。因此,结果流中的元素数量将等于输入流的数量。

Flatmap():获取元素/流流和函数(显式定义)的流,将函数应用到每个流的每个元素,并将所有中间结果流收集为更大的流(“扁平化”)。如果任何元素的处理结果为null,则为“扁平化”的最后一步提供空流。如果输入是几个流,则结果流中的元素数量是所有输入中所有参与元素的总和。