Java stream类中的flatMap()方法

Java 8中引入了Stream API,它允许对数据流进行函数式操作。flatMap()是用于转换流的有用方法之一。

flatMap()是什么

flatMap()方法可以将一个流中的每个元素都转换成一个流,然后把这些流连接成一个流。也就是说,它可以把一个流中的流元素"展平"成一个流。 例如,如果你有一个列表流,通过flatMap()并为每个列表提供一个把它映射成其元素流的函数,就可以获得一个扁平化的元素流。 flatMap()在需要flatten嵌套的流或集合为一个没有嵌套的流时很有用。

flatMap()的使用

下面是一个简单的例子来演示flatMap()的用法:

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

public class FlatMapDemo {

  public static void main(String[] args) {

    // 列表流
    List<Integer> list1 = Arrays.asList(1, 2, 3);
    List<Integer> list2 = Arrays.asList(4, 5, 6);
    List<List<Integer>> listofLists = Arrays.asList(list1, list2);
    
    // 使用 flatMap 把嵌套流展平
    Stream<Integer> flatStream = listofLists.stream()
                                      .flatMap(list -> list.stream());
                                      
    // 打印展平后的流
    flatStream.forEach(System.out::println);

  }

}

这段代码打印出了1到6,通过flatMap()把嵌套的列表展平成一个整数流。 关键在于flatMap()的调用,它对每个列表应用list.stream()把它映射成其元素的流,然后flatten结果流成一个流。 flatMap()是一个非常有用的方法,可以方便地转换和展平嵌套的流和集合为一个扁平化的流进行后续处理。

flatMap()的更多示例

除了基本的展平嵌套流外,flatMap()也可以用于: 将对象流转换为属性流

// Person类
class Person {
  String name;
  int age;
}

// 创建Person对象流  
Stream<Person> personStream = ...

// 将Person对象流转换为name和age属性流
Stream<String> nameStream = personStream.flatMap(person -> Stream.of(person.name)); 

Stream<Integer> ageStream = personStream.flatMap(person -> Stream.of(person.age));

查找列表中的可选对象

// Optional列表
List<Optional<String>> optionals = ...

// 展平Optional并过滤空值
Stream<String> filtered = optionals.stream()
                                   .flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty())
                                   .filter(s -> s != null);  
                                

合并流


Stream<String> s1 = ...
Stream<String> s2 = ...

// 合并为一个流
Stream<String> merged = Stream.of(s1, s2)
                              .flatMap(s -> s);

flatMap()是一个非常灵活的方法,可以用在各种情况下将复杂流简化为扁平化流,这使得后续的map、filter、reduce等操作更简单。合理利用flatMap()可以写出非常简洁高效的流处理代码。