迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > 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 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

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 输出参数

发布时间:2023/10/19 浏览次数:93 分类:Java

本教程演示了 Java 是否有类似 C# 的 out 参数关键字。Java 不支持像 C# 中的 out 和 ref 之类的关键字在方法中通过引用传递,因为值仅在 Java 中传递参数。该值甚至通过引用。

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 开发包,

扫一扫阅读全部技术教程

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

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便