1. 概述

在本文中,我们将介绍Stream的flatMap()方法。

Stream.flatMap()返回将包含通过使用映射函数替换流的每个元素而获得一个新的流。 映射函数将产生流,并且在应用映射函数后将关闭每个映射的流。

2. 快速上手

flatMap()方法的定义如下:

<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
  • 将一个类型为T的流转换为类型为R的流。
  • 为了完成这一个转换,我们需要传递一个映射函数,通过映射函数将类型T的元素转化为类型为R的流。

下面看一个简单的例子。

我们现在有一个需求,需要找出二维整数数组中的偶数。

二维数组如下:

{{1,2},{3,4},{5,6},{7,8,9}}

我们可以使用flatMap()方法将数组展开:

{1,2,3,4,5,6,7,8,9}

然后再通过filter()方法过滤出偶数。

代码如下:

Integer[][] data = {{1,2},{3,4},{5,6},{7,8,9}};
Arrays.stream(data)
  .flatMap(row -> Arrays.stream(row))
  .filter(num -> num%2 == 0)
  .forEach(System.out::println);

输出如下:

2
4
6
8

3 .更多的示例

下面我们来看一下Java API给提供的两个例子。

3.1 List of Lists

如果一个订单里包含多个商品,我们可以使用flatMap()方法来获取所有的订单里的商品:

订单类:

public class Order {
    private List<Item> items;
    // 省略set和get方法
}

商品类:

public class Item {
   private String name;
   private int number;
   // 省略set和get方法
}

最后,使用flatMap()方法的代码:

List<Order> orders = Arrays.asList(
  new Order(Arrays.asList(new Item("AAA", 10),
                          new Item("BBB", 10),
                          new Item("CCC", 10)
                         )),
  new Order(Arrays.asList(new Item("DDD", 10),
                          new Item("EEE", 10),
                          new Item("FFF", 10)
                         )),
  new Order(Arrays.asList(new Item("GGG", 10),
                          new Item("HHH", 10),
                          new Item("III", 10)
                         ))
);
orders.stream()
  .flatMap(order ->  order.getItems().stream())
  .forEach(System.out::println);

输出如下:

Item{name='AAA', number=10}
Item{name='BBB', number=10}
Item{name='CCC', number=10}
Item{name='DDD', number=10}
Item{name='EEE', number=10}
Item{name='FFF', number=10}
Item{name='GGG', number=10}
Item{name='HHH', number=10}
Item{name='III', number=10}

3.2 Files.lines()

Java 8中引入了Files.lines()。它以流的形式读取文件的所有行。

假设,我们有一个包含一些行的文件。

我们需要将所有单词打印出来。

FlatMapTest.txt

java 8
spring framework
spring cloud

代码:

Stream<String> lines = null;
try {
  lines = Files.lines(Paths.get("src/test/resources/FlatMapTest.txt"), StandardCharsets.UTF_8);
} catch (IOException e) {
  e.printStackTrace();
}
lines.flatMap(line -> Stream.of(line.split(" +")))
  .forEach(System.out::println);

输出如下:

java
8
spring
framework
spring
cloud

4. 总结

在本文中,我们将介绍Stream的flatMap()方法。并展示了三个示例。

与往常一样,可以在GitHub上获得代码示例。