303. Java Stream API - 查找元素

文章目录

  • [303. Java Stream API - 查找元素](#303. Java Stream API - 查找元素)
    • [✅ `findFirst()` 与 `findAny()` 方法概述](#✅ findFirst() 与 findAny() 方法概述)
      • [🧠 关键点:](#🧠 关键点:)
    • [🔢 有序流与无序流](#🔢 有序流与无序流)
      • [📌 **有序流**](#📌 有序流)
      • [📌 **无序流**](#📌 无序流)
      • [🎬 示例:处理有序流](#🎬 示例:处理有序流)
    • [🔄 `findAny()` 与并行流](#🔄 findAny() 与并行流)
      • [📌 `findFirst()` 的代价](#📌 findFirst() 的代价)
      • [📌 为什么使用 `findAny()`?](#📌 为什么使用 findAny()?)
      • [🎬 示例:并行流中的 `findFirst()` 和 `findAny()`](#🎬 示例:并行流中的 findFirst() 和 findAny())
    • [🔀 有序流与无序流的区别](#🔀 有序流与无序流的区别)
      • [📌 `unordered()` 方法](#📌 unordered() 方法)
      • [🎬 示例:无序流中的 `findFirst()` 和 `findAny()`](#🎬 示例:无序流中的 findFirst() 和 findAny())
      • [📌 `Set` 的无序性](#📌 Set 的无序性)
    • [⚠️ 需要注意的性能问题](#⚠️ 需要注意的性能问题)
      • [📌 结论](#📌 结论)
    • [🧾 总结](#🧾 总结)

303. Java Stream API - 查找元素


✅ findFirst() 与 findAny() 方法概述

Stream API 提供了两个终止操作来查找流中的元素:

  • findFirst():返回流中的第一个元素。
  • findAny():返回流中的任意一个元素。

这两个方法都返回一个 Optional 类型 ,如果流为空,它们返回的 Optional 也是空的。

🧠 关键点:

  • 如果流为空,返回的 Optional 为空。
  • 需要理解流的 顺序性 ,因为它决定了 findFirst() 返回的是哪个元素。

🔢 有序流与无序流

📌 有序流

有序流是指流中的元素顺序是有意义的,且由 Stream API 保持。比如:

  • 基于 List 创建的流通常是有序的。
  • 有序流中,可以明确地找到"第一个"、"第二个"或"第三个"元素。

📌 无序流

无序流中的元素顺序没有固定,通常在流处理过程中,顺序可能会丢失或是随机的。例如,Set 中的元素没有顺序性。

🎬 示例:处理有序流

java 复制代码
Collection<String> strings = List.of("one", "two", "three", "four", "five");
String first = strings.stream()
    .filter(s -> s.length() == 3)
    .findFirst()
    .orElseThrow();  // 获取第一个匹配的元素

System.out.println("第一个匹配的元素: " + first);
输出:
java 复制代码
第一个匹配的元素: one

在这个例子中,因为流是从 List 创建的,所以是有序流,findFirst() 总是返回列表中的第一个匹配元素。


🔄 findAny() 与并行流

📌 findFirst() 的代价

在并行流中,调用 findFirst() 会带来性能开销,因为它需要确保返回的是流中的第一个元素,即使在并行处理中也要保持顺序。

📌 为什么使用 findAny()?

  • 如果你不关心返回流中的第一个元素,而只是需要流中的任意一个元素,那么应该使用 findAny()。
  • findAny() 没有顺序约束,适用于处理并行流时,能提高性能。

🎬 示例:并行流中的 findFirst() 和 findAny()

java 复制代码
Collection<String> strings = List.of("one", "two", "three", "four", "five");
String result = strings.stream()
    .parallel() // 使用并行流
    .filter(s -> s.length() == 3)
    .findFirst()
    .orElseThrow();  // 获取第一个匹配的元素

System.out.println("并行流中的第一个匹配元素: " + result);

在并行流中,findFirst() 仍然返回 第一个匹配元素 ,但是有性能开销。如果你对顺序不关心,可以使用 findAny():

java 复制代码
String anyResult = strings.stream()
    .parallel()
    .filter(s -> s.length() == 3)
    .findAny()
    .orElseThrow();  // 获取任意一个匹配元素

System.out.println("并行流中的任意匹配元素: " + anyResult);

🔀 有序流与无序流的区别

📌 unordered() 方法

调用 unordered() 方法后,流就变为 无序流 。在无序流中,findFirst() 的结果将不再是第一个元素,而是流中的一个随机元素。

🎬 示例:无序流中的 findFirst() 和 findAny()

java 复制代码
Collection<String> strings = List.of("one", "two", "three", "four", "five");
String first = strings.stream()
    .unordered()  // 将流标记为无序流
    .filter(s -> s.length() == 3)
    .findFirst()
    .orElseThrow();  // 获取第一个匹配元素

System.out.println("无序流中的第一个匹配元素: " + first);

在此情况下,findFirst() 仍然返回一个匹配的元素,但结果会随机。

📌 Set 的无序性

使用 Set 作为源时,元素本身就是无序的。例如:

java 复制代码
Collection<String> strings = Set.of("one", "two", "three", "four", "five");
String first = strings.stream()
    .filter(s -> s.length() == 3)
    .findFirst()
    .orElseThrow();

System.out.println("无序集合中的第一个匹配元素: " + first);

⚠️ 需要注意的性能问题

在并行流中,findFirst() 操作需要确保元素顺序,而这可能会导致额外的性能开销。尤其是当流的处理只关注第一个匹配元素时,使用 findAny() 会更合适。

📌 结论

  • 有序流 :findFirst() 会返回流中的第一个元素。
  • 无序流 :findFirst() 和 findAny() 都会返回流中的一个随机元素。
  • 并行流 :使用 findFirst() 时会有性能开销,findAny() 可以在不需要顺序时提升性能。

🧾 总结

方法 适用场景 顺序性 返回类型
findFirst() 查找第一个匹配的元素 有序流 Optional<T>
findAny() 查找任意一个匹配的元素 无序流 Optional<T>
parallel() 使流并行处理 无序 提升性能
unordered() 使流无序 无序流 随机结果
相关推荐
卷无止境5 小时前
独立开发者的"富矿地带":哪些垂直领域值得你押注一辈子?
后端·python
\光辉岁月/5 小时前
5.java-数组
java·开发语言
Java后端的Ai之路5 小时前
Python进阶探索29_eval内置函数
开发语言·python·探索·eval·内置函数
计算机毕业编程指导师5 小时前
计算机毕设选题推荐:基于Hadoop与Spark的Steam游戏数据分析系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习 深度学习
大数据·hadoop·python·计算机·spark·毕业设计·steam游戏
计算机毕业编程指导师5 小时前
【计算机毕设选题推荐】基于Hadoop+Spark的白鹿抖音评论大数据分析与可视化系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习 深度学习
大数据·hadoop·python·计算机·spark·毕业设计·抖音评论
谢亮_vipxieliang5 小时前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot
Zootopia6265 小时前
飞行力学知识梳理1|飞行性能与稳定性
人工智能·python·算法·机器学习·无人机·学习方法·信息与通信
Y3815326625 小时前
搜索 API 延迟优化:并发数、超时与超时的真实代价
python·搜索引擎
郑州光合科技余经理5 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
2601_962071575 小时前
类变量和全局变量的生命周期有什么区别?
java·开发语言·jvm