过滤掉Java 8流过滤器表达式中的空值,因此不会引发异常

Gloria Santin:

我有一个Java 3流表达式,具有3个过滤器,并且运行良好。我想在大多数值的过滤器中防止出现空指针异常。这是表达式:

if(!purchasedTripSegments.isEmpty()) {
    filteredList = purchasedTripSegments.stream()
        .filter(segment -> PurchasedVendorType.RAIL.equals(segment.getVendorType()))
        .filter(distinctByKeys(segment -> Arrays.asList(segment.getBillingMethod(), 
            segment.getOrigin().getNumberCode(), segment.getDestination().getNumberCode(), 
            segment.getStopOff().getStopOffLocation().getNumberCode()))) 
        .filter(segment -> segment.getBillingMethod().equalsIgnoreCase(BILLING_METHOD_LOCAL) ||
               (segment.getBillingMethod().equalsIgnoreCase(BILLING_METHOD_RULE) &&
                segment.getDestination().getNumberCode() != 
                  segment.getStopOff().getStopOffLocation().getNumberCode())) 
        .collect(Collectors.toList());
}

因此,VendorType不能为null。因此,第一个过滤器就可以了。第2个和第3个过滤器可以为空。对象(来源,目标,StopOff,StopOffLocation)可以为空。并且值(BillingMethod,NumberCode)可以为空。

如果过滤器中的任何值为空,是否可以忽略过滤器?

我尝试添加.filter(Objects::nonNull)一个具有空目标对象的测试用例,并抛出NullPointerException。

更新我更新了billingMethod。但是我不清楚如何使用Optional来避免null检查。

Optional<List<PurchasedTripSegment>> filteredList =  Optional.ofNullable(new ArrayList<>());

if(!purchasedTripSegments.isEmpty()) {
    filteredList = purchasedTripSegments.stream()
     .filter(segment -> PurchasedVendorType.RAIL.equals(segment.getVendorType()))
     .filter(distinctByKeys(segment -> Arrays.asList(segment.getBillingMethod(), 
                            segment.getOrigin().getNumberCode(), 
                            segment.getDestination().getNumberCode(), 
                    segment.getStopOff().getStopOffLocation().getNumberCode()))) 
     .filter(segment -> BILLING_METHOD_LOCAL.equals(segment.getBillingMethod()) 
                  || (BILLING_METHOD_RULE.equals(segment.getBillingMethod()) &&
                               segment.getDestination().getNumberCode() != 
                      segment.getStopOff().getStopOffLocation().getNumberCode())) 
      .collect(Collectors.toList());
}

我不确定如何将您建议的更改应用于过滤器。我尝试按书面形式添加,但无法识别map()。中间过滤器将是最困难的。如何检查每个段的对象和值?

更新按照下面的注释,使用Optional实现Utility方法。

private Optional<Integer> getDestinationCode(PurchasedCostTripSegment purchasedCostTripSegment) {
        return Optional.ofNullable(purchasedCostTripSegment.getDestination()) // empty for 'null'
                .map(Destination::getNumberCode);
    }

我对传入的参数进行空检查。我收到一个错误,该方法getNumberCode无法识别。

纳曼:

诸如的属性billingMethod,只要它可能null位于中List,它仍然应该可以进行比较以获得不同的值。另一方面,可以通过用户FilipRistic建议的方式来解决将它们与其他String常量进行比较的问题

但是,当涉及可能为null的对象时,如果您想进一步安全地访问内部属性,则可以使用访问器Optional并将其链接起来。对于其中的一个示例,虽然您想访问numberCode目的地的值(可能为null),但可以在PurchasedTripSegment类中有一个访问器来公开此内容:

Optional<Integer> getDestinationCode() {
    return Optional.ofNullable(this.getDestination()) // empty for 'null'
                   .map(Node::getNumberCode);
}

通过对其他访问者进行类似的更改,您的总体代码将更新并更改为:

filteredList = purchasedTripSegments.stream()
        .filter(segment -> PurchasedVendorType.RAIL.equals(segment.getVendorType()))
        .filter(distinctByKey(segment -> Arrays.asList(segment.getBillingMethod(),
                segment.getOriginCode(), segment.getDestinationCode(),
                segment.getStopOffLocationCode())))
        .filter(segment -> segment.getBillingMethod().equalsIgnoreCase(BILLING_METHOD_LOCAL) ||
                (segment.getBillingMethod().equalsIgnoreCase(BILLING_METHOD_RULE) &&
                        segment.getDestinationCode().equals(segment.getStopOffLocationCode())))
        .collect(Collectors.toList());

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章