Java Stream中map与flatMap对比详解

Java Stream中map与flatMap对比深入剖析

一、核心差异对比

方法 输入类型 输出类型 适用情境 转换关联
map() Function<T,R> Stream<R> 元素的一对一转换 1:1
flatMap() Function<T,Stream<R>> Stream<R> 元素的一对多转换并合并 1:N

二、map()方法详解

1. 基础功能

将流里的每一个元素变换成另一个对象

2. 典型应用场景
  • 类型的转换操作
  • 提取对象的属性值
  • 进行数值方面的计算
3. 示例代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class MapInstance {
    public static void main(String[] args) {
        // 示例1:字符串转大写
        List<String> termList = Arrays.asList("hello", "world");
        List<String> upperCaseTerms = termList.stream()
                .map(String::toUpperCase)
                .collect(Collectors.toList());
        System.out.println(upperCaseTerms); // [HELLO, WORLD]

        // 示例2:提取对象属性
        class UserInfo {
            String username;
            UserInfo(String username) { this.username = username; }
            String getUserName() { return username; }
        }

        List<UserInfo> userSet = Arrays.asList(
            new UserInfo("Alice"),
            new UserInfo("Bob")
        );

        List<String> userNames = userSet.stream()
                .map(UserInfo::getUserName)
                .collect(Collectors.toList());
        System.out.println(userNames); // [Alice, Bob]
    }
}

三、flatMap()方法详解

1. 基础功能

把每个元素转换成一个流,然后将所有的流合并成一个单一的流

2. 典型应用场景
  • 处理嵌套的集合结构
  • 将字符串拆分成多个元素
  • 合并多个流
3. 示例代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FlatMapInstance {
    public static void main(String[] args) {
        // 示例1:展开嵌套集合
        List<List<String>> nestedData = Arrays.asList(
            Arrays.asList("Java", "Python"),
            Arrays.asList("C++", "Go"),
            Arrays.asList("JavaScript", "TypeScript")
        );

        List<String> languageList = nestedData.stream()
                .flatMap(List::stream)
                .collect(Collectors.toList());
        System.out.println(languageList); 
        // [Java, Python, C++, Go, JavaScript, TypeScript]

        // 示例2:拆分字符串为单词
        List<String> sentenceList = Arrays.asList(
            "Hello World",
            "Java Stream API"
        );

        List<String> wordList = sentenceList.stream()
                .flatMap(sentence -> Arrays.stream(sentence.split(" ")))
                .collect(Collectors.toList());
        System.out.println(wordList); 
        // [Hello, World, Java, Stream, API]
    }
}

四、对比应用案例

场景:学生选课数据处理
import java.util.*;
import java.util.stream.*;

class StudentInfo {
    String studentName;
    List<String> selectedCourses;

    StudentInfo(String studentName, List<String> selectedCourses) {
        this.studentName = studentName;
        this.selectedCourses = selectedCourses;
    }

    List<String> getStudentCourses() { return selectedCourses; }
}

public class CompareUsage {
    public static void main(String[] args) {
        List<StudentInfo> studentList = Arrays.asList(
            new StudentInfo("Alice", Arrays.asList("Math", "Physics")),
            new StudentInfo("Bob", Arrays.asList("History", "Art"))
        );

        // 错误用法:map处理嵌套集合
        List<List<String>> wrongOutcome = studentList.stream()
                .map(StudentInfo::getStudentCourses)
                .collect(Collectors.toList());
        System.out.println("错误结果:" + wrongOutcome); 
        // [[Math, Physics], [History, Art]]

        // 正确用法:flatMap展开嵌套集合
        List<String> rightOutcome = studentList.stream()
                .flatMap(student -> student.getStudentCourses().stream())
                .collect(Collectors.toList());
        System.out.println("正确结果:" + rightOutcome); 
        // [Math, Physics, History, Art]

        // 综合应用:统计所有课程数量
        long courseTotal = studentList.stream()
                .flatMap(student -> student.getStudentCourses().stream())
                .count();
        System.out.println("总课程数:" + courseTotal); // 4
    }
}

五、常见问题解答

Q1:什么时候该用flatMap?

当遇到以下情况时考虑使用flatMap:
- List<List<T>>List<T>
- Stream<Stream<R>>Stream<R>
- 需要把元素拆分成多个子元素的时候

Q2:可以组合使用map和flatMap吗?

可以,常见的组合方式如下:

list.stream()
    .map(...)    // 初步转换
    .flatMap(...) // 展开处理
    .collect(...)
Q3:如何处理多层嵌套?

可以使用多次flatMap来处理多层嵌套,示例如下:

List<List<List<String>>> deepNestedData = ...;
deepNestedData.stream()
    .flatMap(List::stream)  // 展开第一层
    .flatMap(List::stream)  // 展开第二层
    .collect(...);

六、总结对比

操作 输入元素 输出元素数量 最终结果结构
map 单个元素 1个新元素 保持原流的结构
flatMap 单个元素 0-N个新元素 合并成单一流的结构

选择准则
- 需要对单个元素进行简单转换 → 使用map()
- 需要展开嵌套结构/生成多个元素 → 使用flatMap()


以上代码均可直接在Java 8及以上环境中运行,建议在IDE中实际运行测试以加深理解。

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/12646.html

(0)
LomuLomu
上一篇 2025 年 6 月 26 日
下一篇 2025 年 6 月 26 日

相关推荐

  • datagrip破解授权方式与激活码同步

    DataGrip激活码永久破解教程:2025最新补丁下载与使用指南 重要声明:本文涉及的DataGrip破解补丁及激活码均来源于网络收集,严禁用于商业用途,仅限个人学习研究使用。如内容存在侵权问题,请及时联系作者删除。经济条件允许的情况下,强烈建议购买官方正版授权。 DataGrip是JetBrains公司出品的一款专业数据库管理工具,功能强大且全面,完美兼…

    DataGrip激活码 2026 年 1 月 9 日
    16200
  • 百度热搜最新idea激活码免费拿+idea破解教程分享

    本教程适用于 IDEA、PyCharm、DataGrip、Goland 等,支持 JetBrains 全家桶! 话不多说,先放一张最新版 IDEA 成功激活到 2099 年的截图镇楼,爽到飞起! 接下来,我将用图文一步步带你把 IDEA 激活到 2099 年,并且旧版本同样适用! 无论你用的是 Windows、macOS 还是 Linux,我都把资源打包好了…

    IDEA破解教程 2025 年 11 月 9 日
    22600
  • 🔥2025年最新PyCharm永久破解教程 | 附激活码&注册码(支持全家桶)🔥

    🚀本教程适用于Jetbrains全家桶(IDEA、PyCharm、DataGrip、Goland等),亲测有效! 先晒一张最新PyCharm破解成功的截图,有效期直达2099年,稳得很!✨ 无论你是Windows/Mac/Linux系统,还是任何版本的PyCharm,按照本教程操作都能100%激活成功!💪 📥 第一步:下载PyCharm安装包 (已安装可跳过…

    2025 年 6 月 15 日
    46000
  • IDEA 永久激活码在 2025.3 中使用

    重要声明:本教程所涉及的IntelliJ IDEA破解补丁及激活码均来源于网络收集,严禁用于商业用途,仅限个人学习研究使用。若涉及侵权问题,请联系作者删除。如条件允许,强烈建议购买官方正版授权! 话不多说,先展示IDEA 2025.2.1版本破解成功的截图,如下图所示,可以看到已经成功激活到2099年,非常爽! 接下来将通过图文结合的方式,详细讲解如何破解最…

    IDEA破解教程 2026 年 1 月 13 日
    13700
  • 2026国内ChatGPT Plus充值开通攻略

    现在用ChatGPT,开通Plus和不开通的体验差距非常大。开通后不仅响应速度更快、几乎不用排队,还能抢先体验各类新模型,加上代码解释器、文件分析这些专属功能,早就不只是普通聊天工具,更像一个全能生产力助手。但困扰很多国内用户的问题是:要怎么给ChatGPT Plus付款呢? 如果你想直接用国内信用卡,哪怕是Visa/Mastercard,大概率也会被支付拦…

    ChatGPT 2026 年 4 月 7 日
    22600

发表回复

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

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信