Reputation: 33
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
Reputation: 394126
In order to produce a separate total for each Customer
, you need to group the Customer
s by customer ID (using collect(Collectors.groupingBy())
). Then you can use Collectors.summingInt()
to sum the amounts of each group of Customer
s:
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