调试Java Stream()NullPoInterException原因的最佳方法



在Java中,我有以下代码:

return new RestTemplate().getForObject("https://images-api.nasa.gov/search?q=finger", CollectionWrapper.class)
    .getCollection()
    .getItems().stream()
    .map(Item::getLinks)
    .flatMap(List::stream)
    .filter(link-> "preview".equals(link.getRel()))
    .map(Link::getHref)
    .collect(Collectors.toList());

它通过以下错误消息抛出NullPoInterException:

java.lang.NullPointerException: null
    at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:271) ~[na:na]
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[na:na]
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[na:na]
    at [... MyController.java]

我的问题

使用Java开发人员的常见工具调试此NPE的最佳/最简单/最快的方法是什么?

我最好的解决方案(到目前为止(

在JavaScript中重写代码,然后在任何浏览器DevTools JS Console

中运行它
fetch("https://images-api.nasa.gov/search?q=finger").then(data => data.json()).then(data => {
    const result = data
        .collection
        .items
        .map(item => item.links)
        .flat()
        .filter(link => link.rel === "preview")
        .map(link => link.href)
    console.log(result)
})

在Chrome的JS控制台中,这给了我

VM704:7 Uncaught (in promise) TypeError: Cannot read property 'rel' of undefined
    at <anonymous>:7:22
    at Array.filter (<anonymous>)
    at <anonymous>:7:2

换句话说,我正在尝试访问过滤器中缺少"链接"项目的" rel"属性。如果我首先过滤所有没有"链接"的"项目"元素,则我的代码在Java和JavaScript中都没有例外。

但是如何在不复制和运行JavaScript的代码的情况下快速找到此原因?

通常,您可以使用peek()方法在流上打印或执行一些调试。它的工作原理与foreach类似,但返回Stream而不是void。但实际上,每当您尝试访问列表的元素时,您都应该断言列表不是空的,在您的情况下,您可以使用filter()来过滤空列表。

相关内容

最新更新