Java Stream 分组并求和
Java 8 引入了 Stream API,使得对集合数据进行操作更加方便和高效。Stream API 提供了丰富的操作方法,其中一个常用的功能是分组并求和。本文将介绍如何使用 Java Stream 对集合进行分组并求和操作,并给出相应的代码示例。
Stream API 简介
Stream 是 Java 8 中新增的一个用于处理集合数据的 API。它可以让我们以函数式编程的方式对集合进行处理,提供了一套丰富的操作方法,如映射、过滤、排序等。Stream API 的设计思想是将集合数据看作一系列的管道,可以通过不同的操作方法来进行数据的处理和转换。
Stream API 的核心是 Stream 接口,它定义了一系列操作方法,可以分为两大类:中间操作和终端操作。中间操作用于对数据进行处理和转换,可以多次调用;终端操作用于触发数据处理的执行,并返回最终结果。
分组并求和操作
分组并求和是一种常见的数据处理需求。例如,我们有一组订单数据,每个订单包含商品名称和销售额。我们希望按照商品名称对订单进行分组,并计算每个商品的销售总额。使用 Stream API,可以很方便地实现这个功能。
首先,我们需要定义一个订单类,包含商品名称和销售额两个属性:
public class Order {
private String productName;
private double salesAmount;
public Order(String productName, double salesAmount) {
this.productName = productName;
this.salesAmount = salesAmount;
}
// getters and setters
}
接下来,我们创建一组订单数据,并使用 Stream API 对其进行分组并求和操作:
List<Order> orders = Arrays.asList(
new Order("Apple", 100.0),
new Order("Banana", 200.0),
new Order("Apple", 300.0),
new Order("Banana", 400.0)
);
Map<String, Double> sumByProduct = orders.stream()
.collect(Collectors.groupingBy(Order::getProductName, Collectors.summingDouble(Order::getSalesAmount)));
System.out.println(sumByProduct);
上述代码首先创建了一个包含四个订单的列表。然后,我们通过 stream()
方法将列表转换为 Stream 对象,并使用 collect()
方法对订单进行分组操作。其中,groupingBy()
方法用于按照商品名称进行分组,summingDouble()
方法用于对每个分组中的销售额进行求和。最后,我们将分组并求和的结果保存在一个 Map 对象中,并输出结果:
{Apple=400.0, Banana=600.0}
可以看到,通过 Stream API,我们很方便地对订单数据进行了分组并求和操作。
分组并求和的应用场景
分组并求和操作在实际应用中非常常见。它可以用于统计销售数据、计算各类指标等。下面以一个具体的示例来说明分组并求和的应用。
假设我们有一个电商平台,有多个商品类别和多个商家。我们希望统计每个商品类别下每个商家的订单销售总额。首先,我们定义一个商品类别和商家的类:
public class Product {
private String category;
private String name;
public Product(String category, String name) {
this.category = category;
this.name = name;
}
// getters and setters
}
public class Merchant {
private String name;
public Merchant(String name) {
this.name = name;
}
// getters and setters
}
然后,我们创建一组订单数据,并进行分组并求和操作:
List<Order> orders = Arrays.asList(
new Order("Apple", 100.0),
new Order("Banana", 200.0),
new Order("Apple", 300.0),
new Order("Banana", 400.0)
);
Map<Product, Map<Merchant, Double>> sumByCategoryAndMerchant = orders.stream()
.collect(Collectors.groupingBy(
order -> new Product(order.getProductName(), "Category"),
Collectors.groupingBy(
order -> new Merchant("Merchant"),
Collectors.summingDouble(Order::getSalesAmount)
)
));
System.out.println(sumByCategoryAndMerchant);