Следующее находит главного клиента, сначала группируя его по полю 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();
}
Это просто напечатает значения.Но вы можете реструктурировать код, чтобы присвоить их переменной.