使用 java 流实现 map-reduce

Implementation for map-reduce with java streams

我正在尝试在 java Stream 中实现这 1 个命令的 map-reduce 范例。 比如我有一个不同客户的订单列表,每个订单都有订单状态,客户id和订单金额:

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

有人知道吗?

为了为每个 Customer 生成单独的总数,您需要按客户 ID 对 Customer 进行分组(使用 collect(Collectors.groupingBy()))。然后就可以用Collectors.summingInt()求和每组Customer的金额:

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

这将 return 以下 Map:

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