迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Java >

Java 中的 flatMap

作者:迹忆客 最近更新:2023/11/13 浏览次数:

本文介绍 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() 操作也适用于原始数据类型。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Do you understand JavaScript closures?

发布时间:2025/02/21 浏览次数:108 分类:JavaScript

The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.

Do you know about the hidden traps in variables in JavaScript?

发布时间:2025/02/21 浏览次数:178 分类:JavaScript

Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av

How much do you know about the Prototype Chain?

发布时间:2025/02/21 浏览次数:150 分类:JavaScript

The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start

在 Pandas 的列中展平层次索引

发布时间:2024/04/24 浏览次数:1782 分类:Python

在这篇文章中,我们将使用不同的函数来使用 Pandas DataFrame 列来展平层次索引。我们将使用的方法是重置索引和 as_index() 函数。

Pandas 中的 Groupby 索引列

发布时间:2024/04/23 浏览次数:89 分类:Python

本教程将介绍如何使用 Python Pandas Groupby 对数据进行分类,然后将函数应用于类别。通过示例使用 groupby() 函数按 Pandas 中的多个索引列进行分组。

Pandas 中的散点矩阵

发布时间:2024/04/23 浏览次数:125 分类:Python

本教程演示了如何使用 scatter_matrix 函数在 Pandas 中创建散点图。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便