Java Stream API不会主动抛NPE,但因null集合、null元素、flatMap返回null流、map返回null后连锁调用及终止操作误用(如findFirst().get())等不当使用而触发。

Java Stream API 本身不会主动抛出空指针异常(NullPointerException),但异常往往来自你对数据源或中间操作的不当使用。关键不在Stream本身,而在你传给它的数据和lambda表达式里——尤其是null集合、null元素、flatMap返回null流,以及误用终止操作导致的逻辑错误。
确保数据源非null,避免源头崩溃
最常见错误是直接对null集合调用.stream():
-
List<string> list = null; list.stream().filter(...).count();</string>→ 立即抛出NPE - 正确做法:始终在创建流前做防御性判空,推荐用三元运算符或
Collections.emptyList() - 示例:
(list != null ? list : Collections.emptyList()).stream()... - 更优实践:API设计时,方法返回集合应默认返回空集合而非
null;接收参数可用Objects.requireNonNull(list, "list must not be null")提前校验
警惕flatMap返回null流
flatMap要求每个元素映射为一个Stream,若lambda返回null,运行时会触发NPE(尤其在后续调用collect或forEach时):
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 错误写法:
stream.flatMap(item -> item.getSubList() == null ? null : item.getSubList().stream()) - 安全写法:用
Optional.ofNullable()兜底,或显式返回空流:item.getSubList() == null ? Stream.empty() : item.getSubList().stream() - 推荐模式:
Optional.ofNullable(item.getSubList()).map(List::stream).orElseGet(Stream::empty)
map操作中避免返回null后引发连锁问题
map返回null本身不报错,但后续若涉及Optional.get()、flatMap内部解包、或自定义Collector依赖非null值,就会崩:
立即学习“Java免费学习笔记(深入)”;
- 例如:
stream.map(obj -> obj.getName()).flatMap(name -> Stream.of(name.toUpperCase()))→ 若getName()返回null,toUpperCase()触发NPE - 解决方式:在
map中提前过滤或转换,如map(obj -> Optional.ofNullable(obj.getName()).orElse("")),或先filter(Objects::nonNull) - 注意:
filter不能放在map之后再处理null——因为map已执行并可能抛异常
终止操作误用:别让流“白跑”或“重复消费”
终止操作一旦执行,Stream就被消耗,不可复用;且某些操作在空流下行为易被误解:
-
findFirst().get()在空流上会抛NoSuchElementException,不是NPE,但同样致命 → 改用findFirst().orElse(null)或isPresent()判断 -
reduce无初始值时,空流返回Optional.empty();有初始值则正常返回该值 —— 需根据业务明确是否允许空输入 -
collect(Collectors.toList())对空流返回空List,安全;但collect(Collectors.toMap())若key为null或重复,会直接抛异常,需提前filter去null或保证key唯一 - 切记:写了
filter和map没加终止操作,整个链式调用根本不会执行 —— 这不是bug,是Stream惰性求值的特性

















