为什么每个 Java 开发者都应该了解 FlatMap
Java 8 流中的 flatMap 方法是将元素流(通常涉及嵌套或复杂结构)转换为扁平化流的强大工具。以下是对每个方法的解释及实际示例
“虽然本文在起草过程中借助了人工智能工具,但我凭借专业知识对其进行了进一步的塑造和完善。”
1. flatMap(通用流)
定义:
flatMap
是一个中间操作。- 中间操作将一个流转换为另一个流,并允许进行进一步的流操作。
flatMap
中的 “flat” 指的是它能够将集合流(例如Stream<List<T>>
)扁平化成为单个元素流(Stream<T>
)。- 目的: 将原始流中的每个元素转换为其他元素的流(一对多映射),然后将生成的流扁平化为一个连续的流。
示例: 假设你有一个订单列表,每个订单包含一个商品列表。你想要一个包含所有订单中所有商品的扁平列表。
java
复制代码
1class Order {
2 private List<String> lineItems;
3 public Order(List<String> lineItems) {
4 this.lineItems = lineItems;
5 }
6 public List<String> getLineItems() {
7 return lineItems;
8 }
9}
10
11public class Example {
12 public static void main(String[] args) {
13 List<Order> orders = Arrays.asList(
14 new Order(Arrays.asList("item1", "item2")),
15 new Order(Arrays.asList("item3", "item4"))
16 );
17 // 扁平化商品列表
18 List<String> allItems = orders.stream()
19 .flatMap(order -> order.getLineItems().stream())
20 .collect(Collectors.toList());
21 System.out.println(allItems); // [item1, item2, item3, item4]
22 }
23}
另一个示例
java
复制代码
1List<List<Integer>> listOfLists = Arrays.asList(
2 Arrays.asList(1, 2, 3),
3 Arrays.asList(4, 5),
4 Arrays.asList(6, 7, 8)
5);
6List<Integer> flattenedList = listOfLists.stream()
7 .flatMap(List::stream) // 将 Stream<List<Integer>> 扁平化为 Stream<Integer>
8 .collect(Collectors.toList());
9System.out.println(flattenedList); // 输出: [1, 2, 3, 4, 5, 6, 7, 8]
2. flatMapToInt
定义:
- 将原始流中的每个元素转换为一个
IntStream
,并将这些流扁平化为一个单一的IntStream
。
示例: 假设你有一个整数列表的列表,你想要一个包含所有整数的扁平流
java
复制代码
1public class Example {
2 public static void main(String[] args) {
3 List<List<Integer>> listOfLists = Arrays.asList(
4 Arrays.asList(1, 2, 3),
5 Arrays.asList(4, 5, 6)
6 );
7 IntStream intStream = listOfLists.stream()
8 .flatMapToInt(list -> list.stream().mapToInt(Integer::intValue));
9 intStream.forEach(System.out::println); // 输出: 1 2 3 4 5 6
10 }
11}
flatMap 作为中间操作的特点:
- 延迟执行:与所有中间操作一样,
flatMap
是延迟求值的。实际计算只有在调用终端操作(如collect
)时才会发生。 - 结合映射和扁平化:它对流中的元素进行映射,并将生成的嵌套结构扁平化。
3. flatMapToLong
定义:
- 与
flatMapToInt
类似,但适用于LongStream
以处理长整型值。
示例: 将长整型数组流扁平化为一个 LongStream
java
复制代码
1public class Example {
2 public static void main(String[] args) {
3 List<long[]> longLists = Arrays.asList(
4 new long[]{1L, 2L, 3L},
5 new long[]{4L, 5L, 6L}
6 );
7 LongStream longStream = longLists.stream()
8 .flatMapToLong(Arrays::stream);
9 longStream.forEach(System.out::println); // 输出: 1 2 3 4 5 6
10 }
11}
4. flatMapToDouble
定义:
- 与
flatMapToInt
类似,但适用于DoubleStream
以处理浮点型值。
示例: 将双精度数组流扁平化为一个 DoubleStream
关键点
- 扁平化嵌套数据:
flatMap
方法的主要目的是将复杂结构(如列表的列表)“扁平化”为单个流。
2. 中间操作:
- 所有
flatMap
方法都是中间操作,这意味着它们会转换流并允许进行进一步的处理。
3. 映射函数:
- 传递给
flatMap
的函数必须返回一个流(例如Stream
、IntStream
、LongStream
或DoubleStream
)。
4. 处理空值:
- 如果映射函数返回
null
,则会用空流替换它,以避免NullPointerException