【问题标题】:Using Collectors.toMap how to convert the map values使用 Collectors.toMap 如何转换地图值
【发布时间】:2020-01-17 11:42:34
【问题描述】:

我有一个Map<String, List<StartingMaterial>> 我想将列表中的对象转换为另一个对象。 IE。 Map<String, List<StartingMaterialResponse>>

我可以使用 java 流 Collectors.toMap() 做到这一点吗?

我尝试了类似下面的代码。

Map<String, List<StartingMaterial>>  startingMaterialMap = xxxx;

startingMaterialMap.entrySet().stream().collect(Collectors.toMap( Map.Entry::getKey, Function.identity(), (k, v) -> convertStartingMaterialToDto(v.getValue())));

我更改对象的转换代码如下所示,

private StartingMaterialResponse convertStartingMaterialToDto(StartingMaterial sm) {

    final StartingMaterialMatrix smm = sm.getStartingMaterialMatrix();
    final StartingMaterial blending1Matrix = smm.getBlending1Matrix();
    final StartingMaterial blending2Matrix = smm.getBlending2Matrix();

    return new StartingMaterialResponse(
            sm.getId(),
            sm.getComponent().getCasNumber(),
            sm.getDescription(),
            sm.getPriority(),
            String.join(" : ",
                    Arrays.asList(smm.getCarryInMatrix().getComponent().getMolecularFormula(),
                            blending1Matrix != null ? blending1Matrix.getComponent().getMolecularFormula() : "",
                            blending2Matrix != null ? blending2Matrix.getComponent().getMolecularFormula() : ""
                    ).stream().distinct().filter(m -> !m.equals("")).collect(Collectors.toList())),
            smm.getFamily(),
            smm.getSplitGroup());
}

【问题讨论】:

  • 如果Map&lt;String, List&lt;StartingMaterial&gt;&gt; 是由groupingBy 组成的,您可以预先提供Collectors.mapping as a downstream collector。当然,那是您不想单独使用Map&lt;String, List&lt;StartingMaterial&gt;&gt; 的时候。

标签: java java-stream collectors


【解决方案1】:

您可以使用 toMap 收集器,因为您的来源是地图。但是,您必须遍历所有值并将它们中的每一个转换为 valueMapper 中的 DTO 格式。

Map<String, List<StartingMaterialResponse>> result = startingMaterialMap.entrySet().stream()
    .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().stream()
        .map(s -> convertStartingMaterialToDto(s)).collect(Collectors.toList())));

【讨论】:

    【解决方案2】:

    我认为你的意思是:

    startingMaterialMap.entrySet().stream()
            .collect(Collectors.toMap(Map.Entry::getKey,
                    e -> e.getValue().stream()
                            .map(this::convertStartingMaterialToDto)
                            .collect(Collectors.toList()))
            );
    

    【讨论】:

      【解决方案3】:

      这是我解决这个问题的方法:

          Map<String, List<Integer>> deposits = new HashMap<>();
      
          deposits.put("first", Arrays.asList(1, 2, 3));
      
          deposits.forEach((depositName, products) -> {
              products.stream()
                      .map(myIntegerProduct -> myIntegerProduct.toString())
                      .collect(Collectors.toList());
          });
      

      上面的示例将List&lt;Integer&gt; 转换为字符串列表。 在您的示例中,convertStartingMaterialToDto 方法不是 myIntegerProduct.toString()

      forEach 方法遍历映射中的每个 Key-Value 对,您为键和值参数设置一些名称以更具体并保持每个阅读它的人都可以理解的代码。在我的示例中:forEach( (depositName, products)) -&gt; depositName 是键(在我的情况下是字符串),而 products 是键的值(在我的情况下是列表整数)。

      最后你也遍历了这个列表,map 每个项目都变成了一个新类型

      products.stream() .map(myIntegerProduct -> myIntegerProduct.toString())

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-23
        • 2013-06-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多