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 MapExample {
    public static void main(String[] args) {
        // 示例1:字符串转大写
        List<String> words = Arrays.asList("hello", "world");
        List<String> upperCaseWords = words.stream()
                .map(String::toUpperCase)
                .collect(Collectors.toList());
        System.out.println(upperCaseWords); // [HELLO, WORLD]

        // 示例2:提取对象属性
        class User {
            String name;
            User(String name) { this.name = name; }
            String getName() { return name; }
        }
        
        List<User> users = Arrays.asList(
            new User("Alice"),
            new User("Bob")
        );
        
        List<String> names = users.stream()
                .map(User::getName)
                .collect(Collectors.toList());
        System.out.println(names); // [Alice, Bob]
    }
}

三、flatMap()方法详解

1. 基本功能

将每个元素转换为流,然后将所有流合并为一个流

2. 典型应用场景

  • 处理嵌套集合
  • 拆分字符串为多个元素
  • 合并多个流

3. 示例代码

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

public class FlatMapExample {
    public static void main(String[] args) {
        // 示例1:展开嵌套集合
        List<List<String>> nestedList = Arrays.asList(
            Arrays.asList("Java", "Python"),
            Arrays.asList("C++", "Go"),
            Arrays.asList("JavaScript", "TypeScript")
        );
        
        List<String> languages = nestedList.stream()
                .flatMap(List::stream)
                .collect(Collectors.toList());
        System.out.println(languages); 
        // [Java, Python, C++, Go, JavaScript, TypeScript]

        // 示例2:拆分字符串为单词
        List<String> sentences = Arrays.asList(
            "Hello World",
            "Java Stream API"
        );
        
        List<String> words = sentences.stream()
                .flatMap(sentence -> Arrays.stream(sentence.split(" ")))
                .collect(Collectors.toList());
        System.out.println(words); 
        // [Hello, World, Java, Stream, API]
    }
}

四、对比使用案例

场景:学生选课数据处理

import java.util.*;
import java.util.stream.*;

class Student {
    String name;
    List<String> courses;
    
    Student(String name, List<String> courses) {
        this.name = name;
        this.courses = courses;
    }
    
    List<String> getCourses() { return courses; }
}

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

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

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

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

五、常见问题解答

Q1:什么时候该用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>>> deepNested = ...;
deepNested.stream()
    .flatMap(List::stream)  // 展开第一层
    .flatMap(List::stream)  // 展开第二层
    .collect(...);

六、总结对比

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

选择原则

  • 需要简单转换单个元素 → 使用map()
  • 需要展开嵌套结构/生成多个元素 → 使用flatMap()

以上代码均可直接复制到Java 8+环境中运行,建议在IDE中实际测试观察输出结果,以加深理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值