gpt4 book ai didi

java - 使用 Java 8 Streams 映射、聚合和组合总计

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:17:02 26 4
gpt4 key购买 nike

我正在尝试重新创建一个过程来创建一个对象列表,这些对象列表是使用 Java 8 Streams 的另一个对象列表的聚合。

例如,我有一个类,如下所述,它是通过数据库调用或类似方式提供的

public class Order {

private String orderNumber;
private String customerNumber;
private String customerGroup;
private Date deliveryDate;
private double orderValue;
private double orderQty;
}

在我的应用程序的其他地方,我有一个 OrderTotal 类,它表示按客户编号和组对订单进行分组和汇总,并对 orderValue 和 orderQty 的总和进行汇总。 (在 customerGroup 和 customerNumber 上使用 equals 和哈希码)

public class OrderTotal {

private String customerGroup;
private String customerNumber;
private double totalValue;
private double totalQty;
}

我们在 Java 8 之前实现此目的的“长手”方式如下

public Collection<OrderTotal> getTotals(List<Order> orders) {
///map created for quick access to the order total for each order
Map<OrderTotal, OrderTotal> map = new HashMap<>();
///loop through all orders adding to the relevaent order total per iteration
for (Order order : orders) {
OrderTotal orderTotal = createFromOrder(order);
{
///if the order total already exists in the map use that one, otherwise add it to the map.
OrderTotal temp = map.get(orderTotal);
if(temp == null){
map.put(orderTotal, orderTotal);
}else{
orderTotal = temp;
}
}
///add the values to the total
aggregate(orderTotal, order);
}
return map.values();
}

private OrderTotal createFromOrder(Order order) {
OrderTotal orderTotal = new OrderTotal();
orderTotal.setCustomerGroup(order.getCustomerGroup());
orderTotal.setCustomerNumber(order.getCustomerNumber());
return orderTotal;
}

private void aggregate(OrderTotal orderTotal, Order order){
orderTotal.setTotalQty(orderTotal.getTotalQty() + order.getOrderQty());
orderTotal.setTotalValue(orderTotal.getTotalValue() + order.getOrderValue());
}

我一直在研究使用分组依据和缩减函数的收集器,但它们似乎都专注于聚合订单类,而不是在 OrderTotal 类中组合总计。

我正在寻找一个 tidy stream 或 collect 函数来消除此代码中的所有膨胀。

最佳答案

您可以使用 toMap 收集器,如下所示:

Collection<OrderTotal> result = orders.stream()
.map(o -> createFromOrder(o))
.collect(toMap(Function.identity(),
Function.identity(),
(l, r) -> {
aggregate(l, r);
return l;
}))
.values();

请注意,这需要将 aggregate 方法参数更改为 aggregate(OrderTotal orderTotal, OrderTotal order){ ... } 即两个参数都是 OrderTotal 类型

或者您可以完全删除 aggregate 方法并执行 toMap 中的逻辑:

Collection<OrderTotal> result = orders.stream()
.map(o -> createFromOrder(o))
.collect(toMap(Function.identity(),
Function.identity(),
(l, r) -> {
l.setTotalQty(l.getTotalQty() + r.getTotalQty());
l.setTotalValue(l.getTotalValue() + r.getTotalValue());
return l;
}))
.values();

关于java - 使用 Java 8 Streams 映射、聚合和组合总计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56170346/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com