【发布时间】:2019-08-15 16:29:58
【问题描述】:
我有一个订单列表,我应该按两个标准进行分组。
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;
}
}
问题:
有什么办法可以一次性解决上述任务吗?
【问题讨论】:
-
没办法,你需要两个reduce操作,第一个是按人计算当月的所有订单,第二个是通过分组来检测当月的顶级买家
标签: java java-8 java-stream