前提
class Product {
public String name;
public String category;
public String type;
public int id;
//todo:implement equals(), toString() and hashCode()
}
class Item{
public Product product;
public double cost;
}
总结方式
List items = ...;
Map stat = items.stream().collect(groupingBy(
it -> it.product,
Collectors.summarizingDouble(it -> it.cost)
));
// get some product summarizing
long count = stat.get(product).getCount();
double sum = stat.get(product).getSum();
//list all product summarizing
stat.entrySet().forEach(it ->
System.out.println(String.format("%s - count: %d, total cost: %.2f"
, it.getKey(),it.getValue().getCount(), it.getValue().getSum()));
);
合并具有相同产品的项目
首先,您需要在Item类中添加一个qty字段:
class Item{
public int qty;
//other fields will be omitted
public Item add(Item that) {
if (!Objects.equals(this.product, that.product)) {
throw new IllegalArgumentException("Can't be added items"
+" with diff products!");
}
return from(product, this.cost + that.cost, this.qty + that.qty);
}
private static Item from(Product product, double cost, int qty) {
Item it = new Item();
it.product = product;
it.cost = cost;
it.qty = qty;
return it;
}
}
那么您可以使用Collectors#toMap合并具有相同产品的项目:
Collection summarized = items.stream().collect(Collectors.toMap(
it -> it.product,
Function.identity(),
Item::add
)).values();
最后
你可以看到两种方式做同样的事情,但第二种方法更容易在流上运行.以及我在github上检查的两种方式的测试,你可以点击查看更多细节:summarizing items& merge items方式.