【问题标题】:Create a new object by merging two objects in a set having same Id and add the resulting object into a different set通过合并具有相同 Id 的集合中的两个对象来创建一个新对象,并将生成的对象添加到不同的集合中
【发布时间】:2020-01-25 19:55:51
【问题描述】:

我有一组对象,ProductDetails 有以下字段,

public class ProductDetails {

    String productId;

    Set<CityQty> qtyByCities;

}

@EqualsAndHashCode(of = {"name"})
public class CityQty {
    String name;
    int qty;
}

我想将其转换为一组 CityQty,其中每个城市都有所有产品的总数量。

示例输入:

[{"productId":"Item01","qtyByCities":[{"name":"New York", "qty":24},{"name":"Washington", "qty":68}]},
{"productId":"Item02","qtyByCities":[{"name":"New York", "qty":20}]}]

示例输出:

[{"name":"New York", "qty":44},{"name":"Washington", "qty":68}]

我编写了以下代码来实现这一点:

Set<CityQty> cities = new HashSet<>();
setOfItems.stream().flatMap(product -> product.getQtyByCities().stream())
    .forEach(cityQty -> {
        String cityName = cityQty.getName();
        CityQty city = cities.stream()
                             .filter(cityQty -> cityQty.getName().equals(cityName))
                             .findFirst()
                             .orElse(new CityQty(cityName, 0));
        city.setQty(city.getQty() + cityQty.getQty());
        cities.add(city);
});

上述解决方案工作正常,但我正在寻找更优雅的解决方案,可能使用我在这里缺少的任何 Java 8 功能,这不需要我为每个人都遍历 cities 集在forEach lambda 中迭代。

这个问题能不能更高效简洁的解决?

【问题讨论】:

    标签: java dictionary java-8 set java-stream


    【解决方案1】:

    您可以利用Collectors 类。有关详细信息,请参阅javadoc。这是一个使用groupingBy的例子:

    Map<String, Integer> m = setOfItems.stream()
        .flatMap(product -> product.getQtyByCities().stream())
        .collect(groupingBy(CityQty::getName, summingInt(CityQty::getQty)));
    

    您最终会得到一张地图:名称 - 总和。如果你想得到一套,你可以使用map

    m.entrySet().stream().map(e -> new CityQty(e.getKey(), e.getValue())).collect(toSet());
    

    【讨论】:

      猜你喜欢
      • 2021-07-29
      • 1970-01-01
      • 2019-06-05
      • 2021-04-09
      • 2019-08-02
      • 1970-01-01
      • 2015-08-23
      • 1970-01-01
      • 2019-03-05
      相关资源
      最近更新 更多