我有一些使用java stream
api的代码:
boolean isAuthorized = authorizationByTenant.stream()
.filter(auth -> auth.getTenantName().equalsIgnoreCase(tenant))
.map(auth -> auth.getAuthorizedRoutes().get(component))
.flatMap(Collection::stream)
.anyMatch(routeDefinition -> isMatchingRoute(routePath, routeDefinition));
有时我会得到一个指向Exception
行的anyMatch
:
java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:273) ~na:na在java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~na:na在java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~na:na在java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1602) ~na:na在java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipelinejava.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527) ~na:na在java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513) ~na:na在java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~na:na在java.base/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230) ~na:na在java.base/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps在java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~na:na在java.base/java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:632) ~na:na在com.mycompany.routefilter.functionality.FunctionalityService.isAuthorizedRoute(FunctionalityService.java:55) ~classes中!/:1.0-快照在
我的问题是null
是什么?是routeDefinition
吗?为什么它会让电话失败呢?我希望如果routeDefinition
为null,我的方法isMatchingRoute
将返回false。
谢谢。
发布于 2022-06-29 13:02:23
NullPointerException发生在您的.flatMap(Collection::stream)
表达式中。
我创建了一个类似的示例,并将方法引用扩展为lambda。当导致空值时,您将看到堆栈跟踪变得更加清晰。
示例:
Stream.of("foo")
.map(foo -> (List<String>) null)
.flatMap(Collection::stream)
.anyMatch(string -> "gnarly".equals(string)); // LINE 13
引向
Exception in thread "main" java.lang.NullPointerException
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:271)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.Streams$StreamBuilderImpl.tryAdvance(Streams.java:397)
at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:127)
at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:502)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:488)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230)
at java.base/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:196)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:528)
at Test.main(Test.java:13)
当我把它替换为:
Stream.of("foo")
.map(foo -> (List<String>) null)
.flatMap(strings -> strings.stream()) // LINE 11
.anyMatch(string -> "gnarly".equals(string)); // LINE 12
然后例外情况变成:
Exception in thread "main" java.lang.NullPointerException
at Test.lambda$main$1(Test.java:11)
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:271)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.Streams$StreamBuilderImpl.tryAdvance(Streams.java:397)
at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:127)
at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:502)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:488)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230)
at java.base/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:196)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:528)
at Test.main(Test.java:12)
这里,您可以在堆栈跟踪的顶部看到真正的原因在第11行。确实有点混乱,但我想JRE不能报告在方法引用中发生的异常,其行号是准确的。
编辑:关于解决方案,我的IntelliJ建议如下:
过滤器:
.filter(Objects::nonNull)
.flatMap(Collection::stream)
空的安全lambda:
.flatMap(strings -> strings != null ? strings.stream() : null)
发布于 2022-06-29 13:14:54
您的代码在.flatMap(Collection::stream)
上主要是失败的。
这主要是因为您没有在.map(auth -> auth.getAuthorizedRoutes().get(component))
中处理空检查。因此,为了避免这种情况,您可以在调用平台地图之前进行筛选:
boolean isAuthorized = authorizationByTenant.stream()
.filter(auth -> auth.getTenantName().equalsIgnoreCase(tenant))
.map(auth -> auth.getAuthorizedRoutes().get(component))
.filter(auth -> auth.getAuthorizedRoutes().get(component)!= null)
.flatMap(Collection::stream)
.anyMatch(routeDefinition -> isMatchingRoute(routePath, routeDefinition));
我发现的提示是基于堆栈跟踪的java.base/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230) ~[na:na] at
行的。
MatchOps$MatchOp
接受谓词,并确定源流的元素(在您的情况下是从flatMap
生成的流)是否匹配谓词。因此,这证实了您的flatMap正在生成null
值,而null
值又会接收map
调用的输入。
https://stackoverflow.com/questions/72801523
复制相似问题