上周在一个流中遇到了非常奇怪的 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()));
}
我的问题是我在这里处理外部 POJO,因此我无法更改它并使其为空安全,因此我必须调整我的代码。
以下是一些限制:
1) errorList - 此处不能为空,因此调用
.stream()
是安全的 - 当它为空时,它只会返回 false2)
getErrorSegment()
和 getErrorDetails()
都可以是空值,这就是为什么我使用这样的过滤器来确保它们都不是空值3)
getErrorCode()
可以为 null 但它永远不会抛出 NPE 因为它在与 null 匹配时只会返回 false - 我很好。您将如何使该流变得更好?我觉得我的
.filter()
很糟糕,可以做得更好。最近写了很多这样的代码,因为我不再确定流是如何处理空值的,并且不想在 .map()
中获得 NPE,因为它是在空值上调用的 最佳答案
您可以通过这种方式更优雅地过滤 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()));
}
关于Java 8 流 - 如何正确制作 NPE 安全流,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53040979/