stream创建了一个额外的列表 - 如何避免

问题描述 投票:2回答:1

我在找出流式传输和收集数据的正确方法时遇到了问题。

流是以下

  public List<List<CalculatedItemCostPerStore>> getCalcualtedItemCostPerStore() {
    var it = item
        .getQuantities().stream().map(quantities -> {
          Store.StoreCosts<CostType, BigDecimal> storeCosts = quantities.getStore().getStoreCosts();
          return new CalculatedItemCostPerStore(quantities.getStore().getName(), new TreeSet<>(quantities
              .getItemCostEvents()
              .stream()
              .map(e -> new CalculatedItemCost(e.getCostTrigger(), e.getTriggerQuantity().multiply(storeCosts.get(e.getCostTrigger()))))
              .collect(
                  Collectors.toMap(CalculatedItemCost::getCostType, Function.identity(), (a, b) -> new CalculatedItemCost(a.getCostType(), a.getCost().add(b.getCost())))
              ).values()));
        }).collect(Collectors.groupingBy(CalculatedItemCostPerStore::getStore)).values().stream().collect(Collectors.toList());
    return it;
  }

得到了流入

  @Data
  @AllArgsConstructor
  static class CalculatedItemCost implements Comparable<CalculatedItemCost> {
    private CostType costType;
    private BigDecimal cost;

    @Override
    public int compareTo(CalculatedItemCost o) {
      return this.costType.toString().compareTo(o.getCostType().toString());
    }
  }

  @Data
  @AllArgsConstructor
  static class CalculatedItemCostPerStore {
    private String store;
    private TreeSet<CalculatedItemCost> calculatedItemCosts;
  }

和itemCostEvents是一个列表

{
  "createdAt": "2018-08-29T00:00:00",
  "costTrigger": "STORAGE_COST_PER_CBM_PER_DAY",
  "triggerQuantity": 33
}

上面的流创建一个由json下面表示的结果。你可以看到它是一个List<List<CalculatedItemCostPerStore>>

"calcualtedItemCostPerStore": [
    [
      {
        "store": "foo",
        "calculatedItemCosts": [
          {
            "costType": "ADDITIONAL_COST_OFFICE_PER_HOUR",
            "cost": 1368
          },
          {
            "costType": "STORAGE_COST_PER_CBM_PER_DAY",
            "cost": 287.1
          }
        ]
      }
    ],
    [
      {
        "store": "bar",
        "calculatedItemCosts": [
          {
            "costType": "ADDITIONAL_COST_OFFICE_PER_HOUR",
            "cost": 38
          }
        ]
      }
    ]
  ]

可以有任意数量的数量,每个数量可以有一个商店。

我想得到的是如下所示的单个List<CalculatedItemCostPerShop>

"calcualtedItemCostPerStore": [
    {
        "store": "foo",
        "calculatedItemCosts": [
            {
                "costType": "ADDITIONAL_COST_OFFICE_PER_HOUR",
                "cost": 1368
            },
            {
                "costType": "STORAGE_COST_PER_CBM_PER_DAY",
                "cost": 287.1
            }
        ]
    },
    {
        "store": "bar",
        "calculatedItemCosts": [
            {
                "costType": "ADDITIONAL_COST_OFFICE_PER_HOUR",
                "cost": 38
            }
        ]
    }
 ]

我如何调整我的流以获得上述结果?

java java-stream
1个回答
1
投票

由于@ernest_k解决了它 - 在flatMap上使用.values()

public List<CalculatedItemCostPerStore> getCalcualtedItemCostPerStore() {
    return item
        .getQuantities().stream().map(quantities -> {
          Store.StoreCosts<CostType, BigDecimal> storeCosts = quantities.getStore().getStoreCosts();
          return new CalculatedItemCostPerStore(quantities.getStore().getName(), new TreeSet<>(quantities
              .getItemCostEvents()
              .stream()
              .map(e -> new CalculatedItemCost(e.getCostTrigger(), e.getTriggerQuantity().multiply(storeCosts.get(e.getCostTrigger()))))
              .collect(
                  Collectors.toMap(CalculatedItemCost::getCostType, Function.identity(), (a, b) -> new CalculatedItemCost(a.getCostType(), a.getCost().add(b.getCost())))
              ).values()));
        })
        .collect(Collectors.groupingBy(CalculatedItemCostPerStore::getStore))
        .values()
        .stream()
        .flatMap(Collection::stream).collect(Collectors.toList())
        ;
  }
© www.soinside.com 2019 - 2024. All rights reserved.