好的,阿杰,我们来详细讲讲 Java 8 里 map()
和 flatMap()
的用法与区别。
这两个方法常见于 Stream API、Optional、以及 Optional 等场景中,是 Java 函数式编程的核心操作之一。
🧩 一、map()
的基本用法
map()
是一对一映射操作:
对流(Stream)中的每个元素应用一个函数,然后将结果收集成一个新的流。
✅ 示例 1:基本类型映射
import java.util.*;
import java.util.stream.*;
public class MapExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Tom", "Jerry", "Spike");
// map():将每个字符串转成大写
List<String> upperNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(upperNames); // [TOM, JERRY, SPIKE]
}
}
👉 map()
的返回结果与输入元素数量一致,只是值被转换。
🌊 二、flatMap()
的基本用法
flatMap()
是一对多映射 + 扁平化(flatten) 操作:
当你的映射函数返回的是一个 Stream(或集合) 时,flatMap()
会把嵌套的结构“打平”。
✅ 示例 2:List<List> 扁平化
import java.util.*;
import java.util.stream.*;
public class FlatMapExample {
public static void main(String[] args) {
List<List<String>> listOfLists = Arrays.asList(
Arrays.asList("Java", "Python"),
Arrays.asList("C++", "Go")
);
// flatMap():打平嵌套结构
List<String> languages = listOfLists.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
System.out.println(languages); // [Java, Python, C++, Go]
}
}
👉 flatMap()
会先把每个子列表变成流 (List::stream
),再把所有小流合并成一个大流。
🧠 三、对比总结
方法 | 主要作用 | 函数返回类型 | 输出结构 |
---|---|---|---|
map() | 一对一映射 | 任意类型 R | Stream<R> |
flatMap() | 一对多映射 + 扁平化 | Stream<R> | Stream<R> (打平嵌套结构) |
✅ 示例 3:区别对比
List<String> words = Arrays.asList("hello", "world");
// map:得到 Stream<Stream<String>>
List<Stream<String>> mapped = words.stream()
.map(word -> Arrays.stream(word.split("")))
.collect(Collectors.toList());
// flatMap:得到 Stream<String>
List<String> flatMapped = words.stream()
.flatMap(word -> Arrays.stream(word.split("")))
.collect(Collectors.toList());
System.out.println(mapped); // [[h, e, l, l, o], [w, o, r, l, d]] (嵌套流)
System.out.println(flatMapped); // [h, e, l, l, o, w, o, r, l, d]
💡 四、在 Optional 中的应用
示例 4:map()
vs flatMap()
in Optional
Optional<String> name = Optional.of("Tom");
// map: 返回 Optional<Optional<Integer>> ❌
Optional<Optional<Integer>> wrong = name.map(n -> Optional.of(n.length()));
// flatMap: 返回 Optional<Integer> ✅
Optional<Integer> correct = name.flatMap(n -> Optional.of(n.length()));
System.out.println(correct.get()); // 3
📦 五、常见应用场景
场景 | 用法 |
---|---|
集合嵌套(List<List>) | 用 flatMap 打平 |
Optional 嵌套(Optional<Optional>) | 用 flatMap 去除嵌套 |
文本拆分(String → 单词列表) | flatMap(str -> Arrays.stream(str.split(" "))) |
复杂对象映射(如 List<User> → 所有 User 的 addressList ) | users.stream().flatMap(u -> u.getAddresses().stream()) |
发表回复