0

0

Java中如何用Stream对集合进行过滤和映射

冰火之心

冰火之心

发布时间:2025-06-12 16:42:01

|

551人浏览过

|

来源于php中文网

原创

java stream 是一种声明式处理集合的方式,通过操作链实现数据过滤、转换等。其核心思想是将数据源如 list、set 转换为 stream,接着使用 filter() 方法接收 predicate 接口以判断元素是否保留来过滤数据,如用 n -> n > 10 过滤出大于 10 的数字;随后可调用 map() 方法接收 function 接口以转换元素,如 string::touppercase 将字符串转为大写;这些中间操作具备延迟执行特性,只有终端操作如 collect()、foreach()、sum() 等被调用时才执行,且可并行处理,通过 parallelstream() 分解任务提升性能,但需评估线程开销;此外,stream 只能使用一次,消耗后需重新创建;异常处理可通过 try-catch 捕获或 optional 类型安全处理 null 值,确保流操作的健壮性。

Java中如何用Stream对集合进行过滤和映射

Java Stream提供了一种声明式的方式来处理集合数据,核心在于通过一系列操作链,实现数据的过滤、转换等。简单来说,就是把集合变成一个“流”,然后像流水线一样加工它。

Java中如何用Stream对集合进行过滤和映射

解决方案

Java中如何用Stream对集合进行过滤和映射

Java Stream API 允许你以函数式风格对集合进行过滤和映射。其核心思想是将数据源(如 List、Set 等)转换为 Stream,然后应用一系列中间操作(如 filter、map)来转换数据,最后通过终端操作(如 collect、forEach)来产生结果。

立即学习Java免费学习笔记(深入)”;

Java中如何用Stream对集合进行过滤和映射

如何使用 Stream 进行过滤?

过滤操作 filter() 接收一个 Predicate 函数式接口,该接口定义了一个 test() 方法,用于判断元素是否应该被包含在结果流中。

例如,假设你有一个整数列表,想要过滤出所有大于 10 的数字:

List numbers = Arrays.asList(1, 5, 12, 8, 15, 3);

List filteredNumbers = numbers.stream()
                                        .filter(n -> n > 10)
                                        .collect(Collectors.toList());

System.out.println(filteredNumbers); // 输出: [12, 15]

这里,n -> n > 10 就是一个 Predicate 表达式,它判断数字 n 是否大于 10。collect(Collectors.toList()) 则是将过滤后的 Stream 转换回 List。

如何使用 Stream 进行映射?

映射操作 map() 接收一个 Function 函数式接口,该接口定义了一个 apply() 方法,用于将一个元素转换为另一个元素。

例如,假设你有一个字符串列表,想要将每个字符串转换为大写:

List names = Arrays.asList("Alice", "Bob", "Charlie");

List upperCaseNames = names.stream()
                                   .map(String::toUpperCase)
                                   .collect(Collectors.toList());

System.out.println(upperCaseNames); // 输出: [ALICE, BOB, CHARLIE]

String::toUpperCase 是一个方法引用,它等价于 s -> s.toUpperCase(),将字符串 s 转换为大写。

如何同时进行过滤和映射?

你可以将 filter()map() 操作链式调用,先过滤再映射,或者先映射再过滤,取决于你的需求。

例如,假设你有一个 Person 对象列表,想要获取所有年龄大于 20 岁的人的名字,并将名字转换为大写:

class Person {
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

List people = Arrays.asList(
    new Person("Alice", 25),
    new Person("Bob", 18),
    new Person("Charlie", 30)
);

List upperCaseNames = people.stream()
                                     .filter(p -> p.getAge() > 20)
                                     .map(Person::getName)
                                     .map(String::toUpperCase)
                                     .collect(Collectors.toList());

System.out.println(upperCaseNames); // 输出: [ALICE, CHARLIE]

这里,我们先使用 filter() 过滤出年龄大于 20 岁的人,然后使用 map() 获取他们的名字,再使用 map() 将名字转换为大写。

Stream 的延迟执行特性是什么?

Stream 的一个重要特性是延迟执行(Lazy Evaluation)。中间操作(如 filter()map())不会立即执行,而是会等到终端操作(如 collect())被调用时才一起执行。

LongCat AI
LongCat AI

美团推出的AI对话问答工具

下载

这种延迟执行的特性可以提高性能,因为 Stream 可以避免不必要的计算。例如,如果你的 Stream 只需要处理前几个元素,那么 Stream 可以只计算前几个元素,而不需要计算整个集合。

Stream 可以并行处理吗?

Stream 可以通过调用 parallelStream() 方法来并行处理。并行处理可以将任务分解成多个子任务,并在多个线程上同时执行,从而提高处理速度。

例如,假设你想要计算一个大型数字列表中所有大于 10 的数字的总和:

List numbers = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
    numbers.add(i);
}

int sum = numbers.parallelStream()
                 .filter(n -> n > 10)
                 .mapToInt(Integer::intValue)
                 .sum();

System.out.println(sum);

这里,我们使用 parallelStream() 创建一个并行 Stream,然后使用 filter() 过滤出大于 10 的数字,再使用 mapToInt() 将 Integer 对象转换为 int 类型,最后使用 sum() 计算总和。

需要注意的是,并行处理并非总是能提高性能。如果任务过于简单,或者数据量太小,并行处理可能会因为线程切换的开销而降低性能。因此,在使用并行 Stream 之前,需要仔细评估其性能影响。

Stream 只能使用一次吗?

是的,Stream 只能使用一次。一旦你对 Stream 执行了终端操作,Stream 就被“消耗”掉了,不能再次使用。如果你需要再次使用相同的数据,你需要重新创建一个新的 Stream。这其实也符合“流”的概念,用完就没了。

Stream 还有哪些常用的终端操作?

除了 collect()forEach()sum() 之外,Stream 还有很多其他常用的终端操作,例如:

  • count(): 统计 Stream 中元素的数量。
  • min(): 找出 Stream 中最小的元素。
  • max(): 找出 Stream 中最大的元素。
  • findFirst(): 找出 Stream 中第一个元素。
  • findAny(): 找出 Stream 中任意一个元素。
  • anyMatch(): 判断 Stream 中是否存在至少一个元素满足指定条件。
  • allMatch(): 判断 Stream 中是否所有元素都满足指定条件。
  • noneMatch(): 判断 Stream 中是否没有任何元素满足指定条件。
  • reduce(): 将 Stream 中的元素聚合为一个结果。

这些终端操作可以满足各种不同的需求,你可以根据实际情况选择合适的终端操作。

Stream 的异常处理应该如何进行?

在 Stream 操作中,如果某个操作抛出异常,整个 Stream 流程将会中断。为了避免这种情况,你需要对 Stream 操作进行异常处理。

一种常见的做法是使用 try-catch 块来捕获异常,并在 catch 块中进行处理。例如:

List names = Arrays.asList("Alice", "Bob", "Charlie", null);

names.stream()
     .map(name -> {
         try {
             return name.toUpperCase();
         } catch (NullPointerException e) {
             System.err.println("遇到空指针异常: " + e.getMessage());
             return null; // 或者返回一个默认值
         }
     })
     .filter(Objects::nonNull) // 过滤掉 null 值
     .forEach(System.out::println);

在这个例子中,我们使用 try-catch 块来捕获 NullPointerException 异常,并在 catch 块中打印错误信息,然后返回 null 值。最后,我们使用 filter(Objects::nonNull) 来过滤掉 null 值。

另一种做法是使用 Optional 来处理可能为空的值。例如:

List names = Arrays.asList("Alice", "Bob", "Charlie", null);

names.stream()
     .map(name -> Optional.ofNullable(name)
                          .map(String::toUpperCase)
                          .orElse(null))
     .filter(Objects::nonNull)
     .forEach(System.out::println);

在这个例子中,我们使用 Optional.ofNullable(name)name 转换为 Optional 对象。如果 namenull,则 Optional 对象为空。然后,我们使用 map(String::toUpperCase)Optional 对象中的字符串转换为大写。如果 Optional 对象为空,则 map() 方法不会执行。最后,我们使用 orElse(null) 来返回 Optional 对象中的值,如果 Optional 对象为空,则返回 null

总而言之,Java Stream 是一种强大的工具,可以让你以简洁、高效的方式处理集合数据。掌握 Stream API 的使用方法,可以大大提高你的编程效率。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

841

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

742

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

737

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

399

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16926

2023.08.03

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

19

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.7万人学习

C# 教程
C# 教程

共94课时 | 7.1万人学习

Java 教程
Java 教程

共578课时 | 48.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号