[英]Navigate in object with a lot of nulls
我正在尝试在我的代码中实现一个好的设计。 有一个实体 purchaseOrder,我需要在具有 stockOrder 列表的对象内部导航,并且每个 StockOrder 都有一个 StockOrderItem 列表。 不能保证 stockOrder 或 stockOrderItem 存在,所以我需要检查很多空值。 有没有一种优雅的方法来做到这一点?
PurchaseOrder purchaseOrder = purchaseOrderRepository.
findByIdentifierAndBrandId(po.getPurchaseOrderIdentifier(), po.getBrandId());
List<StockOrder> stockOrders = Optional.ofNullable(
purchaseOrder.getStockOrders()).orElse(Collections.emptyList());
for (StockOrder stockOrder : stockOrders) {
for (StockOrderItem stockOrderItem : Optional.
ofNullable(stockOrder.getStockOrderItems()).orElse(Collections.emptyList())) {
InventoryDataLoad inventoryDataload = new InventoryDataLoad();
inventoryDataload.setSku(stockOrderItem.getSku());
inventoryDataLoadList.add(inventoryDataload);
}
}
为集合字段返回空值不是一个好习惯。 考虑到您可以访问这些类,请从 get 方法返回一个空列表:
StockOrder.java
public List<StockOrderItem> getStockOrderItems() {
return this.getStockOrderItems != null this.getStockOrderItems ? Collections.emptyList();
}
或者更好,正如@Ridiculon 在评论中指出的那样,直接使用new ArrayList()
初始化集合字段。
StockOrder.java
private final List<StockOrderItem> stockOrderItems;
public StockOrder() {
this.stockOrderItems = new ArrayList();
}
有了这些,您可以使用更优雅的功能方法来填充您的列表,例如:
List<InventoryDataLoad> inventoryDataLoadList = purchaseOrderRepository
.findByIdentifierAndBrandId(po.getPurchaseOrderIdentifier(), po.getBrandId())
.getStockOrders()
.stream()
.map(StockOrder::getStockOrderItems)
.flatMap(Collection::stream)
.map(item -> {
InventoryDataLoad inventoryDataload = new InventoryDataLoad();
inventoryDataload.setSku(item.getSku());
return inventoryDataload;
})
.collect(Collectors.toList());
如果您无权访问类来更改 get 方法,则可以创建自己的 get 方法:
private List<StockOrderItem> getStockOrderItems(StockOrder stockOrder) {
return stockOrder.getStockOrderItems() != null ? stockOrder.getStockOrderItems() : Collections.emptyList();
}
private List<StockOrder> getStockOrders(PurchaseOrderRepository purchaseOrderRepository, PurchaseOrder po) {
List<StockOrder> stockOrders = purchaseOrderRepository
.findByIdentifierAndBrandId(po.getPurchaseOrderIdentifier(), po.getBrandId())
.getStockOrders();
return stockOrders != null ? stockOrders : Collections.emptyList();
}
然后使用以下方法执行功能方法:
List<InventoryDataLoad> inventoryDataLoadList = getStockOrders(purchaseOrderRepository, po)
.stream()
.map(this::getStockOrderItems)
.flatMap(Collection::stream)
.map(item -> {
InventoryDataLoad inventoryDataload = new InventoryDataLoad();
inventoryDataload.setSku(item.getSku());
return inventoryDataload;
})
.collect(Collectors.toList());
编辑:在这两种情况下,您还可以通过创建一个单独的方法来创建InventoryDataLoad
对象来进一步改进它,例如:
private InventoryDataLoad createInventoryDataLoad(StockOrderItem item) {
InventoryDataLoad inventoryDataload = new InventoryDataLoad();
inventoryDataload.setSku(item.getSku());
return inventoryDataload;
}
接着:
List<InventoryDataLoad> inventoryDataLoadList = getStockOrders(purchaseOrderRepository, po)
.stream()
.map(this::getStockOrderItems)
.flatMap(Collection::stream)
.map(this::createInventoryDataLoad)
.collect(Collectors.toList());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.