我对溪流有问题。我有很多Customer对象,我想计算其中哪一个支付最多。
这是我的样本数据:
class Orders {
private List<Order> orders = new ArrayList<>();
public void prepareData() {
Product socks = new ProductBuilder()
.setPrice(new BigDecimal("23"))
.setCategory(Category.C)
.setName("SOCKS")
.build();
Product jacket = new ProductBuilder()
.setPrice(new BigDecimal("199"))
.setCategory(Category.A)
.setName("JACKET")
.build();
Product watch = new ProductBuilder()
.setPrice(new BigDecimal("100"))
.setCategory(Category.B)
.setName("WATCH CASIO")
.build();
Customer john = new CustomerBuilder()
.setAge(18)
.setName("JOHN")
.setSurname("JOHNSON")
.setEmail("john@johnson.com")
.build();
Customer mike = new CustomerBuilder()
.setAge(20)
.setName("MIKE")
.setSurname("MAX")
.setEmail("mike@max.com")
.build();
Order orderJohn = new OrderBuilder()
.setQuantity(2)
.setCustomer(john)
.setProduct(watch)
.setOrderDate(LocalDate.now())
.build();
Order orderJohn2 = new OrderBuilder()
.setQuantity(4)
.setCustomer(john)
.setProduct(socks)
.setOrderDate(LocalDate.now())
.build();
Order orderMike = new OrderBuilder()
.setQuantity(2)
.setCustomer(mike)
.setProduct(jacket)
.setOrderDate(LocalDate.now())
.build();
orders.add(orderJohn);
orders.add(orderJohn2);
orders.add(orderMike);
}
}现在我应该按客户分组,因为一个客户有很多订单,计算价格*和数量,并选择使用orders.stream()的最大值?我怎么能这么做?
我的类定义:
public class Order {
private Customer customer;
private Product product;
private int quantity;
private LocalDate orderDate;
//get/set
}
public class Customer {
private String name;
private String surname;
private int age;
private String email;
//get/set
}
public class Product {
private String name;
private BigDecimal price;
private Category category;
//get/set
}和建筑商
public class CustomerBuilder {
private Customer customer = new Customer();
public CustomerBuilder setName(String name){
customer.setName(name);
return this;
}
public CustomerBuilder setSurname(String surname){
customer.setSurname(surname);
return this;
}
public CustomerBuilder setAge(int age){
customer.setAge(age);
return this;
}
public CustomerBuilder setEmail(String email){
customer.setEmail(email);
return this;
}
public Customer build() {
return customer;
}
}
public class OrderBuilder {
private Order order = new Order();
public OrderBuilder setCustomer(Customer customer){
order.setCustomer(customer);
return this;
}
public OrderBuilder setProduct(Product product){
order.setProduct(product);
return this;
}
public OrderBuilder setQuantity(int quantity){
order.setQuantity(quantity);
return this;
}
public OrderBuilder setOrderDate(LocalDate orderDate){
order.setOrderDate(orderDate);
return this;
}
public Order build(){
return order;
}
}
public class ProductBuilder {
private Product product = new Product();
public ProductBuilder setCategory(Category category){
product.setCategory(category);
return this;
}
public ProductBuilder setName(String name){
product.setName(name);
return this;
}
public ProductBuilder setPrice(BigDecimal bigDecimal){
product.setPrice(bigDecimal);
return this;
}
public Product build() {
return product;
}
}发布于 2018-10-08 12:54:34
下面通过第一次按customer字段分组(映射到相应的采购值quantity * price的总和)来查找顶级客户。
然后遍历聚合的结果,根据总购买价值找到"max“。
Customer topCustomer = orders.stream()
.collect(Collectors.groupingBy(Order::getCustomer,
Collectors.mapping(
order -> order.getProduct()
.getPrice()
.multiply(new BigDecimal(order.getQuantity())),
Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))))
.entrySet().stream()
.max(Comparator.comparing(Entry::getValue))
.map(Entry::getKey)
.orElse(null);需要注意的是,这假设hashCode()和equals()在Customer中被正确覆盖,这样分组才能正确工作。
编辑:
如果还需要购买总量,则需要获得完整的条目,而不是映射到键(下面的代码是基于上面的代码段):
Optional<Entry<Customer, BigDecimal>> topCustomerEntry = orders.stream()
.collect(Collectors.groupingBy(Order::getCustomer,
Collectors.mapping(order ->
order.getProduct()
.getPrice()
.multiply(new BigDecimal(order.getQuantity())),
Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))))
.entrySet().stream()
.max(Comparator.comparing(Entry::getValue));
BigDecimal topValue = null; //total value for top customer
Customer customer = null; //customer with most purchases
if(topCustomerEntry.isPresent()) {
topValue = topCustomerEntry.get().getValue();
customer = topCustomerEntry.get().getKey();
}这只会打印值。但是您可以重新构造代码,将它们分配给一个变量。
发布于 2018-10-08 12:48:40
如果您需要花费最多的客户(例如,通过电子邮件):
orders.stream()
.collect(Collectors.toMap(
x -> x.getCustomer().getEmail(),
x -> x.getProduct().getPrice().multiply(new BigDecimal(x.getQuantity())),
BigDecimal::add))
.entrySet()
.stream()
.max(Entry.comparingByValue())
.ifPresent(System.out::println);https://stackoverflow.com/questions/52702369
复制相似问题