我有这个问题需要使用 Java 8 流来解决,但到目前为止我还没有成功。
我有:
public class Customer {
String id;
String firstName;
String lastName;
}
public class Order {
private final String id;
Set<OrderLine> orderLines = new HashSet<>();
Customer customer;
}
public class OrderLine {
Product product;
Integer quantity;
}
public class Product {
String name;
BigDecimal price;
}
所有对象都有自己的 equals 实现,因此可以比较对象。
这是我必须迭代的数据:
List<Order> orders = new ArrayList<>();
Customer customer1 = new Customer(randomId(), "Will", "Sanders");
Customer customer2 = new Customer(randomId(), "Jonh", "Doe");
Product p1 = new Product("Book 1", new BigDecimal("50.00"));
Product p2 = new Product("Book 2", new BigDecimal("19.00"));
Product p3 = new Product("Book 3", new BigDecimal("100.00"));
orders.add(new Order(randomId(), customer1).addOrderLine(p1, 1));
orders.add(new Order(randomId(), customer1).addOrderLine(p2, 1));
orders.add(new Order(randomId(), customer2).addOrderLine(p3, 1));
我想知道哪个客户给了公司更多的钱。
我已经使用这样的 foreach 解决了这个问题:
orders.forEach(order -> {
order.getOrderLines().forEach(orderLine -> {
if(!map.containsKey(order.getCustomer())) {
map.put(order.getCustomer(), orderLine.getProduct().getPrice());
} else {
map.put(order.getCustomer(),map.get(order.getCustomer()).add(orderLine.getProduct().getPrice()));
}
});
});
Customer c = Collections.max(map.entrySet(), Comparator.comparing(Map.Entry::getValue)).getKey();
但我想知道一种用流解决这个问题的方法。
我的第一个想法是改变这个
一个 Map
有什么建议吗?
谢谢。
最佳答案
让我们一步一步来。
- 如何获取订单行的价格?
BigDecimal getPrice(OrderLine orderLine) {
return orderLine.getProduct()
.getPrice()
.multiply(BigDecimal.valueOf(orderLine.getQuantity()));
}
- 如何获得订单的总价?
BigDecimal getPrice(Order order) {
return order.getOrderLines()
.stream()
.map(orderLine -> getPrice(orderLine))
.collect(reducing(BigDecimal.ZERO, BigDecimal::add));
}
- 现在假设您已经实现了上述方法,您如何确定每位客户花费的总金额?
Map<Customer, BigDecimal> totalPerCustomer =
orders.stream()
.collect(groupingBy(Order::getCustomer,
reducing(BigDecimal.ZERO, o -> getPrice(o), BigDecimal::add)));
- 既然您已将所有信息存储在方便的 map 中,那么您如何确定哪个客户花了最多的钱?
Optional<Customer> topCustomer =
totalPerCustomer.entrySet()
.stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey);
请注意,如果订单列表为空,topCustomer
将等于 Optional.empty()
。
关于java - 如何将嵌套对象列表缩减为 Map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66544780/