如何在 Java 中使用流 API 过滤集合

JavaJavaBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

Java 流 API 提供了一种强大且通用的方式来处理数据集合。在本教程中,我们将探讨如何利用流 API 来过滤集合,从而使你能够高效地提取所需的数据。无论你是 Java 初学者还是经验丰富的开发者,本指南都将为你提供知识和技能,以简化你的数据处理任务。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/DataStructuresGroup(["Data Structures"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/FileandIOManagementGroup(["File and I/O Management"]) java/DataStructuresGroup -.-> java/collections_methods("Collections Methods") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/arraylist("ArrayList") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/hashmap("HashMap") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/iterator("Iterator") java/FileandIOManagementGroup -.-> java/files("Files") java/FileandIOManagementGroup -.-> java/read_files("Read Files") java/FileandIOManagementGroup -.-> java/io("IO") java/FileandIOManagementGroup -.-> java/stream("Stream") subgraph Lab Skills java/collections_methods -.-> lab-415586{{"如何在 Java 中使用流 API 过滤集合"}} java/arraylist -.-> lab-415586{{"如何在 Java 中使用流 API 过滤集合"}} java/hashmap -.-> lab-415586{{"如何在 Java 中使用流 API 过滤集合"}} java/iterator -.-> lab-415586{{"如何在 Java 中使用流 API 过滤集合"}} java/files -.-> lab-415586{{"如何在 Java 中使用流 API 过滤集合"}} java/read_files -.-> lab-415586{{"如何在 Java 中使用流 API 过滤集合"}} java/io -.-> lab-415586{{"如何在 Java 中使用流 API 过滤集合"}} java/stream -.-> lab-415586{{"如何在 Java 中使用流 API 过滤集合"}} end

Java 流 API 简介

Java 流 API 是 Java 8 中引入的一项强大功能,它允许你以声明式和函数式的风格处理数据集合。流提供了一种对数据执行各种操作的方式,例如过滤、映射、排序和归约,而无需显式迭代或可变状态。

理解流

流是一系列元素的序列,支持对这些元素执行各种操作以进行计算。流可以从各种数据源创建,例如集合、数组,甚至 I/O 资源。流提供了一种流畅的 API,允许你将多个操作链接在一起,使你的代码更具表现力和可读性。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = numbers.stream();
stream.filter(n -> n % 2 == 0)
    .map(n -> n * 2)
    .forEach(System.out::println);

在上面的示例中,我们从一个整数列表创建一个流,过滤偶数,将它们映射为其两倍的值,然后打印结果。

使用流的优点

  1. 声明式编程:流允许你以更声明式的方式表达你的意图,专注于你想要实现的目标,而不是如何实现它。
  2. 并行性:流可以轻松并行化,使你能够利用多核处理器并提高性能。
  3. 惰性求值:流是惰性的,这意味着操作仅在需要最终结果时才执行,这可以提高效率。
  4. 流畅的 API:流 API 提供了一种流畅且富有表现力的方式将多个操作链接在一起,使你的代码更具可读性和可维护性。

探索流操作

流提供了广泛的操作,可用于操作你的数据。一些最常见的操作包括:

  • 过滤:根据给定的谓词选择元素。
  • 映射:使用函数转换元素。
  • 排序:根据比较器对元素进行排序。
  • 归约:将元素组合成单个结果。
  • 收集:将结果收集到新的数据结构中。

在以下部分中,我们将更深入地探讨流 API 在过滤集合方面的具体用法。

使用流过滤集合

过滤是使用 Java 流 API 对集合执行的最常见操作之一。过滤允许你根据给定的谓词从集合中选择元素的子集。

应用过滤器

filter() 方法用于对流应用过滤器。此方法接受一个 lambda 表达式或方法引用作为参数,该参数表示过滤条件。

List<String> names = Arrays.asList("John", "Jane", "Bob", "Alice");
Stream<String> filteredNames = names.stream()
                                 .filter(name -> name.startsWith("J"));
filteredNames.forEach(System.out::println);

在上面的示例中,我们从一个名字列表创建一个流,然后使用 filter() 方法仅选择以字母 “J” 开头的名字。

链接多个过滤器

你可以链接多个 filter() 调用来对流应用多个过滤条件。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Stream<Integer> filteredNumbers = numbers.stream()
                                      .filter(n -> n % 2 == 0)
                                      .filter(n -> n > 5);
filteredNumbers.forEach(System.out::println);

在这个示例中,我们首先过滤数字以仅选择偶数,然后应用第二个过滤器以仅选择大于 5 的偶数。

将过滤器与其他操作结合

过滤可以与其他流操作(如映射、排序和归约)结合使用,以创建更复杂的数据转换。

List<Person> persons = Arrays.asList(
    new Person("John", 30),
    new Person("Jane", 25),
    new Person("Bob", 35),
    new Person("Alice", 28)
);

List<String> youngAdultNames = persons.stream()
                                    .filter(p -> p.getAge() >= 18 && p.getAge() < 30)
                                    .map(Person::getName)
                                    .collect(Collectors.toList());

System.out.println(youngAdultNames);

在这个示例中,我们首先过滤 Person 对象列表以仅选择年轻人(18 岁至 30 岁之间),然后映射每个 Person 对象的 Name 属性,最后将结果收集到一个新列表中。

通过理解使用 Java 流 API 进行过滤的强大功能,你可以有效地操作和处理你的数据集合。在下一节中,我们将探索更多应用过滤器的实际示例。

应用过滤器:实际示例

既然你已经对使用 Java 流 API 进行过滤的基础知识有了扎实的理解,那么让我们通过一些实际示例来巩固你的知识。

过滤字符串

假设你有一个字符串列表,并且你只想选择那些具有特定长度或以某个特定字符开头的字符串。

List<String> words = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");

// 过滤长度大于 5 个字符的单词
List<String> longWords = words.stream()
                             .filter(word -> word.length() > 5)
                             .collect(Collectors.toList());
System.out.println(longWords); // [banana, cherry, elderberry]

// 过滤以 'a' 开头的单词
List<String> wordsStartingWithA = words.stream()
                                     .filter(word -> word.startsWith("a"))
                                     .collect(Collectors.toList());
System.out.println(wordsStartingWithA); // [apple, date]

过滤数字

你也可以使用流 API 来过滤数值数据,例如整数或双精度数。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// 过滤偶数
List<Integer> evenNumbers = numbers.stream()
                                 .filter(n -> n % 2 == 0)
                                 .collect(Collectors.toList());
System.out.println(evenNumbers); // [2, 4, 6, 8, 10]

// 过滤大于 5 的数字
List<Integer> numbersGreaterThan5 = numbers.stream()
                                         .filter(n -> n > 5)
                                         .collect(Collectors.toList());
System.out.println(numbersGreaterThan5); // [6, 7, 8, 9, 10]

过滤自定义对象

你还可以对自定义对象(如 Person 对象)的集合应用过滤器。

class Person {
    private String name;
    private int age;

    // 获取器、设置器和构造函数
}

List<Person> persons = Arrays.asList(
    new Person("John", 30),
    new Person("Jane", 25),
    new Person("Bob", 35),
    new Person("Alice", 28)
);

// 过滤年龄大于 30 岁的人
List<Person> personsOlderThan30 = persons.stream()
                                       .filter(p -> p.getAge() > 30)
                                       .collect(Collectors.toList());
System.out.println(personsOlderThan30); // [Person(name=Bob, age=35)]

// 过滤名字以 'J' 开头的人
List<Person> personsWithNameStartingWithJ = persons.stream()
                                                 .filter(p -> p.getName().startsWith("J"))
                                                 .collect(Collectors.toList());
System.out.println(personsWithNameStartingWithJ); // [Person(name=John, age=30), Person(name=Jane, age=25)]

通过探索这些实际示例,你现在应该对如何在 Java 中有效地使用 filter() 方法来操作你的集合有了更好的理解。

总结

在本教程结束时,你将对如何使用 Java 流 API 过滤集合有扎实的理解。你将了解各种可用的过滤方法,例如 filter()distinct()limit(),以及如何将它们应用于你的特定用例。通过所学的知识,你将能够编写更高效、更易于维护的 Java 代码,优化你的数据处理工作流程,并充分发挥流 API 的潜力。