java - 通过合并具有相同 Id 的集合中的两个对象来创建一个新对象,并将生成的对象添加到不同的集合中
问题描述
我有一组对象, 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 功能,这不需要我为lambdacities
内的每次迭代遍历集合。forEach
这个问题能不能更有效、更简洁地解决?
解决方案
你可以利用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());
推荐阅读
- c++ - 已解决 - boost::interprocess::interprocess_condition::timed_wait() 编译器错误
- c++ - 使用 do while 循环验证输入
- python - 通过过滤字段访问模型/类属性
- python - Django:子查询的平均值作为查询结果的多个注释
- rabbitmq - 获取队列中的最新消息
- spring - 与 Spring Cloud Config Server 的集成测试
- shell - 将大文件从驱动器下载到 colab
- ggplot2 - ggplot和图例中的多个符号
- visual-studio-code - 如何修复“找不到文件'.../node_modules/dotenv/types'。” 来自 jsconfig.json 的错误?
- python - 有没有办法让我的 python 文本文件无法打开/无法读取