gpt4 book ai didi

Java Streams - 按两个条件汇总结果分组

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

我有一个订单列表,我应该按两个标准对其进行分组。

Order_Id| Customer |    Date    | Amount |
1 | "Sam" | 2019-03-21 | 100 |
2 | "Nick" | 2019-03-21 | 102 |
3 | "Dan" | 2019-03-21 | 300 |
4 | "Sam" | 2019-04-21 | 400 |
5 | "Jenny" | 2019-04-21 | 220 |
6 | "Jenny" | 2019-04-12 | 330 |

对于当前示例,应该找到每个月总金额的最高买家:

{
MARCH: { customer='Dan', amount=300 },
APRIL: { customer='Jenny', amount=550 }
}

我找到了一个解决方案:

public class Main {

public static void main(String[] args) {
List<Order> orders = List.of(
new Order(1L, "Sam", LocalDate.of(2019, 3, 21), 100L),
new Order(2L, "Nick", LocalDate.of(2019, 3, 21), 102L),
new Order(3L, "Dan", LocalDate.of(2019, 3, 21), 300L),
new Order(4L, "Sam", LocalDate.of(2019, 4, 21), 400L),
new Order(5L, "Jenny", LocalDate.of(2019, 4, 21), 220L),
new Order(6L, "Jenny", LocalDate.of(2019, 4, 12), 330L)
);

solution1(orders);
}

private static void solution1(List<Order> orders) {
final Map<Month, Map<String, Long>> buyersSummed = new HashMap<>();

for (Order order : orders) {
Map<String, Long> customerAmountMap = buyersSummed.computeIfAbsent(order.getOrderMonth(), mapping -> new HashMap<>());
customerAmountMap.putIfAbsent(order.getCustomer(), 0L);
Long customerAmount = customerAmountMap.get(order.getCustomer());
customerAmountMap.put(order.getCustomer(), customerAmount + order.getAmount());
}

final Map<Month, BuyerDetails> topBuyers = buyersSummed.entrySet().stream()
.collect(
toMap(Entry::getKey, customerAmountEntry -> customerAmountEntry.getValue().entrySet().stream()
.map(entry -> new BuyerDetails(entry.getKey(), entry.getValue()))
.max(Comparator.comparingLong(BuyerDetails::getAmount)).orElseThrow())
);

System.out.println(topBuyers);
}

}

我使用的数据模型:

class BuyerDetails {
String customer;
Long amount;

public BuyerDetails(String customer, Long amount) {
this.customer = customer;
this.amount = amount;
}

public String getCustomer() {
return customer;
}

public Long getAmount() {
return amount;
}

}

class Order {

Long id;
String customer;
LocalDate orderDate;
Long amount;

public Order(Long id, String customer, LocalDate orderDate, Long amount) {
this.id = id;
this.customer = customer;
this.orderDate = orderDate;
this.amount = amount;
}

public Long getId() {
return id;
}

public String getCustomer() {
return customer;
}

public LocalDate getOrderDate() {
return orderDate;
}

public Month getOrderMonth() {
return getOrderDate().getMonth();
}

public Long getAmount() {
return amount;
}
}

问题:

有没有办法在一个流中解决上述任务?

最佳答案

尝试使用 groupingBysummingLongcomparingLong,如下所示

Map<Month, BuyerDetails> topBuyers = orders.stream()
.collect(Collectors.groupingBy(Order::getOrderMonth,
Collectors.groupingBy(Order::getCustomer,
Collectors.summingLong(Order::getAmount))))
.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
order -> order.getValue().entrySet().stream()
.max(Comparator.comparingLong(Map.Entry::getValue))
.map(cust -> new BuyerDetails(cust.getKey(), cust.getValue())).get()));

输出

{
"MARCH": { "customer": "Dan", "amount": 300 },
"APRIL": { "customer": "Jenny", "amount": 550 }
}

关于Java Streams - 按两个条件汇总结果分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57480592/

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