Реализация карты-уменьшить с помощью Java-потоков - PullRequest
0 голосов
/ 06 мая 2018

Я пытаюсь реализовать парадигму map-Reduce этой 1 команды в потоке Java. Например, у меня есть список заказов для разных клиентов, каждый заказ имеет статус заказа, идентификатор клиента и сумму заказа:

class Customer
{
    String custId;
    String orderDate;
    String status;
    Integer amount;

    Customer(String custId, String orderDate, String status, Integer amount)
    {
         this.custId = custId;
         this.orderDate = orderDate;
         this.status = status;
         this.amount = amount;
    }
}

List<Customer> customers = Arrays.asList(
       new Customer("cust1", "01/01/2018", "A", 500 ),
       new Customer("cust1", "01/03/2018", "A", 150),
       new Customer("cust1", "01/01/2018", "A", 100),
       new Customer("cust2", "01/01/2018", "A", 53),
       new Customer("cust2", "01/01/2018", "A", 15 ),
       new Customer("cust2", "01/01/2018", "A", 1500 ),
       new Customer("cust3", "01/01/2018", "A", 845),
       new Customer("cust3", "01/01/2018", "B", 47),
       new Customer("cust4", "01/01/2018", "A", 86));

Я бы хотел получить сумму от суммы каждого клиента.

Делая что-то подобное, не группируйте сумму по клиенту, а рассчитывайте общую сумму всех клиентов:

int total = customers
                .stream()
                .filter(a->a.status.equals("A"))
               // .map(a-> a.amount)
                .map(a-> Map(a.custId, a.amount))
                .reduce(0, (x,y)-> x+y); 

У кого-нибудь есть идеи?

1 Ответ

0 голосов
/ 06 мая 2018

Чтобы получить отдельную сумму для каждого Customer, необходимо сгруппировать Customer s по идентификатору клиента (используя collect(Collectors.groupingBy())). Затем вы можете использовать Collectors.summingInt() для суммирования сумм каждой группы Customer s:

Map<String,Integer> totals = 
    customers.stream()
    .filter(a->a.status.equals("A"))
    .collect(Collectors.groupingBy(Customer::getID,
                                   Collectors.summingInt(Customer::getAmount)));

Это вернет следующее Map:

{cust1=750, cust2=1568, cust3=845, cust4=86}
...