Java Stream中map与flatMap对比超详细教程
目录
- 一、核心区别对比
- 二、map()方法详解
- 1. 基本功能
- 2. 典型应用场景
- 3. 示例代码
- 三、flatMap()方法详解
- 1. 基本功能
- 2. 典型应用场景
- 3. 示例代码
- 四、对比使用案例
- 场景:学生选课数据处理
- 五、常见问题解答
- Q1:什么时候该用flatMap?
- Q2:可以组合使用map和flatMap吗?
- Q3:如何处理多层嵌套?
- 六、总结对比
一、核心区别对比
方法 | 输入类型 | 输出类型 | 适用场景 | 转换关系 |
---|---|---|---|---|
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 getNa编程客栈me() { 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") ); python List<String> languages = nestedList.stream() .flatMap(List::stream) .collect(Collectors.toList()); System.out.println(languages); // [Java, Python, C++, Go, JavaScript, TypeScript] // 示例2:拆分字符串为单词 List<String> www.devze.comsentences = 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; } } NflRehsCns 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()
以上代码均可直www.devze.com接复制到Java 8+环境中运行,建议在IDE中实际测试观察输出结果,以加深理解。
到此这篇关于Java Stream中map与flatMap对比的文章就介绍到这了,更多相关Java map与flatMap对比内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论