簡體   English   中英

在包含大量空值的對象中導航

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM