Java 8使用Optional避免空指针检查问题

4

是否可能像这样编写代码,而不必检查元素是否为空且集合是否为空:

 response.getBody()
    .getRequestInformation()
    .getRequestParameters().get(0)
    .getProductInstances().get(0)
    .getResultParameters()

我发现了类似于这篇文章的东西:http://winterbe.com/posts/2015/03/15/avoid-null-checks-in-java/
基本上,我想要实现的是在层级结构中避免多次检查对象是否为空或者集合是否为空的if语句。根据我以上面的帖子所读到的,使用Optional可以自动处理“空检查”。
如果已经有解决方案,请原谅我造成的重复,并请指引我参考该方案。

1
你到底在问什么?如果这与Java 9中的新API有关,你必须具体说明。 - E net4
1
你在http://winterbe.com/posts/2015/03/15/avoid-null-checks-in-java/的哪个部分遇到问题了?要么使用`Optional.map`进行链式操作,要么捕获NPE/AIOOBE异常。 - lexicore
抱歉,不是Java 9,打错了 :) - Aleksandar
除非将整个代码块包裹在 try/catch 中,否则无法精确地编写您所编写的内容。要使用 Optional,您需要确保调用的方法确实返回 Optional,或者在每个步骤中使用 Optional.of 进行包装。然后,您可以像您链接的示例中那样链接 map 调用。 - kaqqao
1个回答

7
如果您想链接 Optional ,可以使用其 map(Function<? super T,? extends U> mapper) 方法,仅在映射函数不为 null 时调用它,并使用 flatMap(Stream :: findFirst)来获取您的 Collection 的第一个元素作为下一个:
Optional<List<ResultParameterClass>> parameters = Optional.ofNullable(response)
    .map(ResponseClass::getBody)
    .map(BodyClass::getRequestInformation)
    .map(RequestInformationClass::getRequestParameters)
    .map(Collection::stream)
    .flatMap(Stream::findFirst)
    .map(RequestParameterClass::getProductInstances)
    .map(Collection::stream)
    .flatMap(Stream::findFirst)
    .map(ProductInstanceClass::getResultParameters);

如果 Optional 中存在列表,是否可能返回该列表?如果不存在,是否可以返回类似于 new ArrayList<ResultParameterClass>() 的内容?

是的,你只需要使用orElseGet(Supplier<? extends T> other)orElse(T other)来提供默认值,结果不再是一个Optional,而是一个List<ResultParameterClass>

所以代码如下:

List<ResultParameterClass> parameters = Optional.ofNullable(response)
    ...
    .map(ProductInstanceClass::getResultParameters)
    .orElseGet(ArrayList::new);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接