Java 8流 - 如何正确地使NPE安全流

ohw*_*ppp 4 java java-stream

上周在一个流中出现了非常奇怪的NPE,这让我遇到了很多麻烦,所以现在我觉得在使用Stream时我对NPE过于安全.

这是我现在的方法:

private boolean matchSomeError(final List<ErrorAtMessageLevel> errorList) {
    return errorList.stream()
        .filter(errorAtMessageLevel -> errorAtMessageLevel.getErrorSegment() != null && errorAtMessageLevel.getErrorSegment().getErrorDetails() != null)
        .map(errorAtMessageLevel -> errorAtMessageLevel.getErrorSegment().getErrorDetails())
        .anyMatch(errorDetails -> SOME_FANCY_ERROR_CODE.equals(errorDetails.getErrorCode()));
}
Run Code Online (Sandbox Code Playgroud)

我的问题是我在这里处理外部POJO所以我无法更改它并使其为null安全所以我必须调整我的代码.

这里有一些限制:1)errorList - 这里不能为null所以调用.stream()是安全的 - 当它为空时它将返回false 2)getErrorSegment()并且getErrorDetails()都可以为null这就是为什么我使用这样的过滤器以确保它们都不是是null 3)getErrorCode()可以为null但它永远不会抛出NPE,因为它只会在与null匹配时返回false - 很好.

你会如何改善这条小溪?我觉得我.filter()很糟糕,可以做得更好.最近写了很多这样的代码,因为我不确定流是如何处理null并且不想让NPE进入,.map()因为它被调用为null

Era*_*ran 8

您可以null通过这种方式更优雅地过滤掉:

private boolean matchSomeError(final List<ErrorAtMessageLevel> errorList) {
    return errorList.stream()
        .map(ErrorAtMessageLevel::getErrorSegment)
        .filter(Objects:nonNull)
        .map(ErrorSegment::getErrorDetails)
        .filter(Objects:nonNull)
        .anyMatch(errorDetails -> SOME_FANCY_ERROR_CODE.equals(errorDetails.getErrorCode()));
}
Run Code Online (Sandbox Code Playgroud)