在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; } 

您可以使用Optional作为您的目的。

 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 fbList = rp.getFareBreakdownList(); if (fbList != null) { List pfList = fb.get(0).getPassengerFareList(); if (pfList != null) { List 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 call(); static  SafeCallable of(T value) { return () -> value; } // ?. operator default  SafeCallable then(Function step) { return then(step, () -> null); } // ?: operator default T orElse(T value) { return then(identity(), () -> value).call(); } default  SafeCallable then(Function step, Supplier 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 ""; } }