迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Java >

Java 8 Stream 中 map() 和 flatMap() 的区别

作者:迹忆客 最近更新:2023/02/08 浏览次数:

map()flatmap() 是新功能 Java 8 中的两个重要操作。它们都代表功能操作,它们也是 java.util.stream.Stream 类中的方法,但是 map 用于转换,而 flatmap 用于两者 变换和扁平化,这就是它被称为平面图的原因。 map()flatmap() 函数之间的主要区别在于,当我们使用 map() 时,它会对流的每个元素应用一个函数,并将该函数返回的值存储到一个新的 Stream 中。 通过这种方式,一个流被转换为另一个流,就像字符串流被转换为整数流,其中每个元素都是相应流的长度。

要记住的关键是 map() 中用于转换的函数返回单个值。 如果 map() 使用一个函数,而不是返回单个值,而是返回一个值流,那么我们将拥有一个值为流的流,而 flatmap() 用于将其扁平化为值流。

例如,如果我们有一个包含 {"12", "34"} 的字符串流,以及一个返回给定字符串排列列表的方法 getPermutations()。 当我们使用 map 将该函数应用于每个 Stream String 时,将得到类似 [["12","21"],["34","43"]] 的内容,但是如果我们使用 flatmap,我们将得到一个 Stream of 字符串,例如 [“12”、“21”、“34”、“43”]

在本文中,我们将看到几个工作示例,以更好地理解 Java 中 map() 和 flatmap() 之间的区别。 顺便说一下,这也是一个流行的 Java Stream 和 Lambda 问题,如果你要去面试,最好复习一下概念并更好地理解 map 和 flatmap 之间的区别。

我知道理解 map()flatMap() 函数并不容易,特别是如果我们之前没有进行过任何函数式编程。 我也遇到过同样的情况,我花了一些时间才真正理解 map 和 flatMap 的用途。


Stream.map() 在 Java 8 中如何工作? 例子

Stream.map() 函数执行映射功能操作,即它接受一个 Stream 并将其转换为另一个 Stream。 它对 Stream 的每个元素应用一个函数,并将返回值存储到新的 Stream 中。

通过这种方式,我们可以将字符串流转换为整数流,如果我们提供 length() 函数,其中整数可以是字符串的长度。 这是一个非常强大的功能,在处理 Java 中的集合时非常有用。

这是 Java 8 中 Stream.map() 的示例:

List listOfIntegers = Stream.of("1", "2", "3", "4")
                    .map(Integer::valueOf)
                    .collect(Collectors.toList());

在此示例中,我们有一个表示数字的字符串值流,通过使用 map() 函数,我们已将此流转换为整数流。 如何? 通过在 Stream 的每个元素上应用 Integer.valueOf()。 这就是“1”转换为整数 1 的方式,依此类推。 转换完成后,我们通过使用收集器将流转换为列表,将结果收集到列表中。


Stream.flatMap() 在 Java 8 中的工作原理 - 示例

Stream.flatMap() 函数,顾名思义,就是map和flat操作的结合。 这意味着我们首先应用 map 函数,然后展平结果。 关键区别在于 map 操作使用的函数返回值流或值列表而不是单个值,这就是我们需要展平的原因。 当你扁平化一个 Stream of Stream 时,它会被转换成 Stream of values。

要了解什么是扁平化流,请考虑具有“两个级别”的结构,例如 [ [1,2,3],[4,5,6],[7,8,9] ]。 它基本上是一个包含三个以上列表的大列表。 扁平化意味着将其转换为“一级”结构,例如 [ 1,2,3,4,5,6,7,8,9 ] 即只有一个列表。

简而言之,

  • 展平前 - 整数列表流
  • 展平后 - 整数流

这是一个代码示例,可以更好地理解 flatMap() 函数:

List evens=Arrays.asList(2,4,6);
List odds=Arrays.asList(3,5,7);
List primes=Arrays.asList(2,3,5,7,11);
List numbers=Stream.of(evens,odds,primes).
        flatMap(list->list.stream()).
        collect(Collectors.toList());
System.out.println("flattend list: "+numbers);

输出结果

flattend list: [2, 4, 6, 3, 5, 7, 2, 3, 5, 7, 11]

我们可以看到我们使用 flatMap() 函数将三个列表合并为一个。 对于映射,我们可以看到我们使用了 list.stream() 函数,它返回多个值而不是单个值。 最后,我们将扁平化的流收集到一个列表中。 如果需要,我们可以使用 forEach() 方法打印最终列表。


Java 8 中的 Stream.map() 与 Stream.flatMap()

简而言之,这是 Java 8 中 map() 与 flatMap() 之间的主要区别:

  • 传递给 map() 操作的函数返回单个值。
  • 传递给 flatMap() 操作的函数返回一个 Stream 值。
  • flatMap() 是 map 和 flat 操作的结合。
  • map() 仅用于转换,而 flatMap() 用于转换和展平。

现在让我们看一个示例 Java 程序,以更好地理解 flatMap()map() 之间的区别。


显示 map 与 flatMap 之间差异的 Java 程序

这是我们的示例 Java 程序,用于演示 Java 8 中 Stream 类的 map()flatMap() 函数之间的真正区别。正如我之前告诉大家的,map() 用于通过应用一个 Stream 将一个 Stream 转换为另一个 Stream flatMap() 作用于每个元素,而 flatMap() 既进行转换又进行展平。

flatMap() 函数可以接受一个列表流,并返回一个由所有这些列表组合而成的值流。 在下面的示例中,我们将结果收集到一个列表中,但我们也可以使用 Java 8 的 forEach() 方法打印它们。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


public class Java8Demo {
    public static void main(String args[]) {
        // foods which helps in weight loss
        List<String> loseWeight = new ArrayList<>();
        loseWeight.add("avocados");
        loseWeight.add("beans");
        loseWeight.add("salad");
        loseWeight.add("oats");
        loseWeight.add("broccoli");
        System.out.println("list of String : " + loseWeight);

        List listOfInts = loseWeight.stream().map(s -> s.length()).collect(Collectors.toList());
        System.out.println("list of ints generate by map(): " + listOfInts);

        List<List> listOfListOfNumber = new ArrayList<>();
        listOfListOfNumber.add(Arrays.asList(2, 4));
        listOfListOfNumber.add(Arrays.asList(3, 9));
        listOfListOfNumber.add(Arrays.asList(4, 16));
        System.out.println("list of list : " + listOfListOfNumber);

        List listOfIntegers = (List) listOfListOfNumber.stream().flatMap(list -> list.stream()).collect(Collectors.toList());
        System.out.println("list of numbers generated by flatMap : " + listOfIntegers);
    }
}

Java 8 Stream 中 map() 和 flatMap() 的区别

我们可以看到,在第一个示例中,map() 方法使用的函数返回一个值,即传递给它的字符串的长度,而在 flatMap() 的情况下,该方法返回一个流,这基本上是我们的 多个值。

这就是 Java 8 中 map()flatMap() 之间的区别。如果大家只想将一个 Stream 转换为另一个 Stream,其中每个元素都转换为一个值,则应该使用 map()

如果 map 操作使用的函数返回多个值并且大家只需要一个包含所有值的列表,请使用 flatMap()

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Do you understand JavaScript closures?

发布时间:2025/02/21 浏览次数:108 分类:JavaScript

The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.

Do you know about the hidden traps in variables in JavaScript?

发布时间:2025/02/21 浏览次数:178 分类:JavaScript

Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av

How much do you know about the Prototype Chain?

发布时间:2025/02/21 浏览次数:150 分类:JavaScript

The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start

Pandas map()

发布时间:2024/04/24 浏览次数:1652 分类:Python

本教程解释了我们如何使用 Series.map()方法将 Pandas Series 的值替换为另一个值。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便