Java 中的 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()
操作也适用于原始数据类型。
相关文章
Java 中的 volatile 关键字
发布时间:2023/11/13 浏览次数:173 分类:Java
-
本文讨论了 Java 中的 volatile 关键字及其优缺点,并举例说明了如何使用。Java 是一种非常流行的编程语言,通过了解 Java,我们可以很容易地理解它为什么会在编程社区中获得这样的地位。
Java 中的 StringUtils
发布时间:2023/11/13 浏览次数:80 分类:Java
-
本文介绍 Java 中的 StringUtils 类是什么。本文介绍什么是 StringUtils 以及如何在 Java 中使用它来处理字符串。StringUtils 是一个用于处理 String 的类,它提供了比 Java String 类更多的实用方法。
修复 Java NoClassDefFoundError 错误
发布时间:2023/11/13 浏览次数:199 分类:Java
-
本文介绍如何修复 Java 中的 NoClassDefFoundError。在 Java 语言中,错误是主要由于缺乏资源而发生的异常。此外,错误无法在编译时捕获并在运行时发生。
在 Java 中扩展 Comparable
发布时间:2023/10/19 浏览次数:97 分类:Java
-
本教程展示了如何在 Java 中清除 StringBuilder 本指南将了解在 Java 中扩展 Comparable 接口。它写成 Comparable
。它是一个由 Java 中的许多类实现的接口。
Java 中的 Predicate 是什么
发布时间:2023/10/19 浏览次数:109 分类:Java
-
本文介绍 Java 8 中的 Predicate 接口。本教程通过 Java 示例介绍 Predicate 接口。Predicate 是 Java 中的一个接口,用作 lambda 表达式或方法引用的目标赋值。
Java 中的 parameter 与 argument
发布时间:2023/10/19 浏览次数:84 分类:Java
-
本文介绍 Java 中 parameter 和 argument 的区别。本教程通过 Java 中的示例介绍 parameter 和 argument 之间的区别。
在 Java 中画一个圆
发布时间:2023/10/19 浏览次数:189 分类:Java
-
本教程介绍如何在 Java 中使用几个函数画圆在本文中,我们将介绍如何使用用于创建 GUI 组件的库 java.awt 和 javax.swing 在 Java 中绘制一个圆。
在 Java 中画一个三角形
发布时间:2023/10/19 浏览次数:143 分类:Java
-
本教程介绍了如何在 Java 中画一个三角形。在本文中,我们将学习如何在 Java 中绘制一个三角形。我们使用 AWT(Abstract Window Component Toolkit),这是最早的 Java 开发包,