merav
merav

Reputation: 33

Implementation for map-reduce with java streams

I'm trying to implement map-reduce paradigm this 1 command in java Stream. For example, I have a list of orders for various customers, each order has status of order, the customer id and the amount of the order:

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));

I would like to get the sum of the amount of each customer.

Doing something like this, doesn't group the sum by the customer, but calculate the total sum of all customers:

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); 

Does someone have any idea?

Upvotes: 2

Views: 301

Answers (1)

Eran
Eran

Reputation: 394126

In order to produce a separate total for each Customer, you need to group the Customers by customer ID (using collect(Collectors.groupingBy())). Then you can use Collectors.summingInt() to sum the amounts of each group of Customers:

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

This will return the following Map:

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

Upvotes: 4

Related Questions