Java 中的 flatMap
-
Java 中的
flatMap
函数 -
在 Java 中如何使用
flatMap()
方法 -
从 Java 中的
flatMap
中删除重复项 -
在 Java 中过滤
flatMap
元素 -
flatMap
和原始类型 - 结论
本教程介绍 flatMap
以及如何在 Java 中使用它。
flatMap
是 Java 流中的一个操作/函数,用于在执行某些功能性任务后获取新流。在这里,我们将讨论 flatMap()
操作。
此操作是 map()
操作的扩展。此函数应用于每个流元素并生成新值流。
然后将这些新流的生成元素复制到最近创建的流中,该流用作方法的返回值。
Java 中的 flatMap
函数
flatMap()
函数的签名是:
<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
flatMap
是一个中间操作。中间操作是惰性操作,在 Stream 实例上调用,在它们完成处理后,它们返回一个 Stream 实例。
flatMap()
操作是 map()
和 flat()
操作的组合。这意味着 flatMap()
操作首先应用 map()
操作,然后将结果展平。
此方法采用映射器,该函数将应用于传入的 Stream
的每个元素。
Java 中的扁平化
我们先来了解一下什么是扁平化。展平列表会将两个或多个级别列表转换为单个级别列表。
两个 2 级列表的示例是:
[[ "I" ], [ "Love" ], [ "Delft", "Stack" ]]
扁平化后的上述列表转换为:
["I", "Love", "Delft", "Stack"]
生成的列表是单级列表。
扁平化列表的必要性
有必要对一个列表进行扁平化处理,因为处理几个 Stream 级别是很困难、很复杂、很容易出错的。
我们可以使用 Stream.flatMap()
操作将两个 Stream 级别转换为单个级别 Stream。我们将在本文后面使用一个示例来理解这一点。
在 Java 中如何使用 flatMap()
方法
在这个例子中,我们首先使用 stream()
方法从 List 创建了一个对象流。每个对象都是公司的程序员。
我们将首先创建一个类来代表公司中的开发人员/程序员。
import java.util.HashSet;
import java.util.Set;
class Programmer {
private String name;
private Set<String> languages_known;
public Programmer(String name) {
this.name = name;
this.languages_known = new HashSet<>();
}
public void addLanguage(String lang) {
this.languages_known.add(lang);
}
public Set<String> getLanguages() {
return languages_known;
}
}
我们现在将初始化对象并创建一个列表列表,其中包含整个公司程序员已知的所有语言。然后,我们将扁平化该列表以了解团队中的所有语言。
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class SimpleTesting {
public static void main(String[] args) {
Programmer raj = new Programmer("Raj");
raj.addLanguage("Java");
raj.addLanguage("Dart");
raj.addLanguage("go");
raj.addLanguage("groovy");
Programmer karan = new Programmer("Karan");
karan.addLanguage("Java");
karan.addLanguage("Python");
Programmer chahal = new Programmer("Chahal");
chahal.addLanguage("Dart");
chahal.addLanguage("Javascript");
List<Programmer> team = new ArrayList<>();
team.add(raj);
team.add(karan);
team.add(chahal);
System.out.println("Programming languages in the team: ");
List<String> languages = team.stream()
.map(Programmer::getLanguages)
.flatMap(Collection::stream)
.collect(Collectors.toList());
System.out.println(languages);
}
}
输出:
Programming languages in the team:
[Java, groovy, go, Dart, Java, Python, Javascript, Dart]
在上面的示例中,我们首先使用流 API 创建了所有程序员的流。之后,我们使用 map()
函数创建了每个程序员都知道的语言列表流。
从 Java 中的 flatMap
中删除重复项
然后我们使用 flatMap()
操作展平这个列表,并将结果流转换为一个列表。请注意,生成的 List 有一些重复值;我们使用 duplicate()
操作来消除这些。
看看下面的代码。
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class SimpleTesting {
public static void main(String[] args) {
Programmer raj = new Programmer("Raj");
raj.addLanguage("Java");
raj.addLanguage("Dart");
raj.addLanguage("go");
raj.addLanguage("groovy");
Programmer karan = new Programmer("Karan");
karan.addLanguage("Java");
karan.addLanguage("Python");
Programmer chahal = new Programmer("Chahal");
chahal.addLanguage("Dart");
chahal.addLanguage("Javascript");
List<Programmer> team = new ArrayList<>();
team.add(raj);
team.add(karan);
team.add(chahal);
System.out.println("Programming languages in the team: ");
List<String> languages = team.stream()
.map(Programmer::getLanguages)
.flatMap(Collection::stream)
.distinct()
.collect(Collectors.toList());
System.out.println(languages);
}
}
输出:
Programming languages in the team:
[Java, groovy, go, Dart, Python, Javascript]
在 Java 中过滤 flatMap
元素
如果我们想要获取除 Dart
之外的所有语言,我们可以使用 filter()
函数和 flatMap()
。看看下面的代码。
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class SimpleTesting {
public static void main(String[] args) {
Programmer raj = new Programmer("Raj");
raj.addLanguage("Java");
raj.addLanguage("Dart");
raj.addLanguage("go");
raj.addLanguage("groovy");
Programmer karan = new Programmer("Karan");
karan.addLanguage("Java");
karan.addLanguage("Python");
Programmer chahal = new Programmer("Chahal");
chahal.addLanguage("Dart");
chahal.addLanguage("Javascript");
List<Programmer> team = new ArrayList<>();
team.add(raj);
team.add(karan);
team.add(chahal);
System.out.println("Programming languages in the team: ");
List<String> languages = team.stream()
.map(Programmer::getLanguages)
.flatMap(Collection::stream)
.distinct()
.filter(x -> !x.equals("Dart"))
.collect(Collectors.toList());
System.out.println(languages);
}
}
输出:
Programming languages in the team:
[Java, groovy, go, Python, Javascript]
flatMap
和原始类型
Java Stream API 还为原始数据类型(如 int、float、long)提供了单独的操作,如 flatMapto{primitive type}
以扁平化原始类型的 Stream。
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class SimpleTesting {
public static void main(String[] args) {
int[] Je_array = {3, 5, 2, 35, 85, 32, 23, 43, 12};
Stream<int[]> JE_streamArray = Stream.of(Je_array);
IntStream JE_intStream = JE_streamArray.flatMapToInt(x -> Arrays.stream(x));
JE_intStream.forEach(x -> System.out.println(x));
}
}
输出:
3
5
2
35
85
32
23
43
12
结论
我们已经讨论了 flatMap()
操作以及为什么需要它。我们还讨论了 Java Stream API 如何为原始数据类型提供单独的 flatMap()
操作。
请注意,普通的 flatMap()
操作也适用于原始数据类型。