在java8中处理多个Null检查

在下面的情况下,而不是多个空检查,我计划添加一些可读的代码。 可能是在java 8的流/地图的帮助。 有人能帮助我吗?

private String getRailsServiceClass(IRailsComponent railsComponent) { String serviceClass = ""; if (railsComponent != null && railsComponent.getRailOffer() != null && railsComponent.getRailOffer().getRailProducts().get(0).getRailProduct() != null && railsComponent.getRailOffer().getRailProducts().get(0).getRailProduct().getFareBreakdownList() != null && railsComponent.getRailOffer().getRailProducts().get(0).getRailProduct().getFareBreakdownList().get(0).getPassengerFareList() != null && railsComponent.getRailOffer().getRailProducts().get(0).getRailProduct().getFareBreakdownList().get(0).getPassengerFareList().get(0).getPassengerSegmentFareList() != null && railsComponent.getRailOffer().getRailProducts().get(0).getRailProduct().getFareBreakdownList().get(0).getPassengerFareList().get(0).getPassengerSegmentFareList().get(0).getCarrierServiceClassDisplayName() != null) { return railsComponent.getRailOffer().getRailProducts().get(0).getRailProduct().getFareBreakdownList().get(0).getPassengerFareList().get(0).getPassengerSegmentFareList().get(0).getCarrierServiceClassDisplayName(); } return serviceClass; } 

您可以使用可选的为您的目的。

 String serviceClass = Optional.ofNullable(railsComponent) .map(IRailsComponent::getRailOffer) .map(RailOffer::getRailProducts) ... .orElse(""); 

你的代码是不好的,因为在每次检查时,你必须一次又一次地获得列表中的项目。 这是很多的I / O。

没有使用任何API(如此之前的Java 8解决方案)您可以通过检查每个项目来清理代码(取决于每个类的可访问性,但是这里是完全开发的条件

 RailComponent rc = getRailComponent(); if (rc != null) { RailOffer ro = rc.getRailOffer() if (ro != null) { RailProduct rp = ro.getRailProducts().get(0).getRailProduct(); if (rp != null) { List<FareBreakDown> fbList = rp.getFareBreakdownList(); if (fbList != null) { List<PassengerFare> pfList = fb.get(0).getPassengerFareList(); if (pfList != null) { List<PassengerSegmentFare> psfList = pfList.get(0).getPassengerSegmentFareList(); if (psfList != null) { String carrierServiceClassDisplayName = psfList.get(0).getCarrierServiceClassDisplayName(); if (carrierServiceClassDisplayName != null) { return carrierServiceClassDisplayName; } } } } } } } 

一旦你减少了代码的冗长,你会发现这并不是那么重要

受Kotlin 安全调用操作员的启发?. & elivs opreator ?: ,您可以链接自定义的SafeCallable 。 例如:

 String serviceClass = SafeCallable.of(railsComponent) .then(IRailsComponent::getRailOffer) .then(RailOffer::getRailProducts) .then(products -> products.get(0)) .then(...) .orElse(""); 

SafeCallable

 interface SafeCallable<T> { T call(); static <T> SafeCallable<T> of(T value) { return () -> value; } // ?. operator default <R> SafeCallable<R> then(Function<T, R> step) { return then(step, () -> null); } // ?: operator default T orElse(T value) { return then(identity(), () -> value).call(); } default <R> SafeCallable<R> then(Function<T, R> step, Supplier<R> otherwise) { T value = call(); return value == null ? otherwise::get : () -> step.apply(value); } } 

如果这些null的任何一个都很少,我会使用try catch块:

 private String getRailsServiceClass(IRailsComponent railsComponent) { try { return railsComponent.getRailOffer().getRailProducts().get(0) .getRailProduct().getFareBreakdownList().get(0).getPassengerFareList().get(0) .getPassengerSegmentFareList().get(0).getCarrierServiceClassDisplayName(); } catch (NullPointerException e) { return ""; } }