findFirst返回Optional以避免空指针,适用于获取流中第一个元素;需用orElse等解包,配合filter可找首个匹配项,并行流中仍按遭遇顺序但性能不如findAny。

findFirst 是 Stream API 中用于获取流中第一个元素的方法,返回一个 Optional 类型结果,避免空指针异常。
基本用法:直接调用 findFirst
适用于已知流非空、或能安全处理空结果的场景:
- 对普通集合转成的流,如
List,findFirst返回第一个插入的元素(注意:对无序流如parallelStream(),结果不保证是“逻辑第一个”) - 必须用
.orElse(...)、.orElseGet(...)或.orElseThrow(...)解包Optional,否则无法直接使用值
示例:
List<String> list = Arrays.asList("apple", "banana", "cherry");String first = list.stream().findFirst().orElse("default"); // 结果为 "apple"
配合 filter 使用:查找满足条件的第一个元素
这是最常见用途——先筛选再取首个匹配项:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- filter 后的流可能为空,
findFirst自动返回Optional.empty() - 推荐用
orElse(null)或orElseThrow()明确表达业务意图
示例:
List<Integer> numbers = Arrays.asList(1, 3, 5, 4, 6);Integer firstEven = numbers.stream()
.filter(n -> n % 2 == 0)
.findFirst()
.orElse(null); // 结果为 4
注意并行流中的行为
在 parallelStream() 中调用 findFirst 仍保证返回「遇到的第一个」元素(按流的遭遇顺序),但性能可能不如 findAny:
- 如果只关心“存在一个即可”,用
findAny效率更高 - 若逻辑强依赖顺序(如找列表里第一个偶数),必须用
findFirst,且建议用普通stream()避免意外
常见错误与规避
- 忘记处理
Optional—— 直接调用.get()可能抛NoSuchElementException - 在空集合上调用后未设默认值,导致后续 NPE
- 误以为
findFirst在所有流中都严格按原始顺序 —— 实际取决于数据源和中间操作(如sorted()会影响顺序)
安全写法示例:
String result = list.stream().filter(s -> s.startsWith("a"))
.findFirst()
.orElse("not found");

















