分组求和
时间: 2025-07-01 14:06:05 浏览: 1
### 分组求和操作
Java 8 的 Stream API 提供了强大的功能,可以对集合数据进行分组并同时执行聚合操作(如求和)。这种能力在处理业务逻辑中非常常见,例如统计订单金额、计算库存数量等。
以下是一个典型的示例:假设有一个包含多个对象的列表,每个对象具有分类字段和数值字段,目标是根据分类字段进行分组,并对数值字段进行求和:
```java
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
class Item {
private String category;
private BigDecimal amount;
// 构造函数、getter 和 setter
public Item(String category, BigDecimal amount) {
this.category = category;
this.amount = amount;
}
public String getCategory() {
return category;
}
public BigDecimal getAmount() {
return amount;
}
}
public class GroupingSumExample {
public static void main(String[] args) {
List<Item> items = Arrays.asList(
new Item("Electronics", new BigDecimal("100.50")),
new Item("Clothing", new BigDecimal("50.25")),
new Item("Electronics", new BigDecimal("200.75")),
new Item("Clothing", new BigDecimal("75.00"))
);
Map<String, BigDecimal> result = items.stream()
.collect(Collectors.groupingBy(
Item::getCategory,
Collectors.reducing(BigDecimal.ZERO, Item::getAmount, BigDecimal::add)
));
System.out.println(result); // 输出: {Clothing=125.25, Electronics=301.25}
}
}
```
上述代码中使用 `Collectors.groupingBy` 对 `Item` 按照 `category` 字段进行分组,然后通过 `Collectors.reducing` 实现对 `BigDecimal` 类型的 `amount` 字段进行求和[^2]。该方法确保了精度不会丢失,适用于财务计算等高要求场景。
此外,如果数据结构较为简单,可以直接使用 `groupingBy` 配合 `counting()` 或 `summingDouble()` 等内置收集器实现更简洁的操作。例如,对字符串列表进行计数统计:
```java
List<String> fruits = Arrays.asList("apple", "banana", "apple", "orange", "banana", "apple");
Map<String, Long> fruitCount = fruits.stream()
.collect(Collectors.groupingBy(
Function.identity(),
Collectors.counting()
));
System.out.println(fruitCount); // 输出: {orange=1, banana=2, apple=3}
```
此示例中,`Function.identity()` 表示直接以元素本身作为分组键,而 `Collectors.counting()` 则用于统计每组的元素数量[^1]。
对于复合字段分组的情况,可以通过嵌套的 `groupingBy` 来实现多级分组。例如,按部门和职位分组并求和员工薪资:
```java
Map<String, Map<String, BigDecimal>> groupedResult = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.groupingBy(
Employee::getPosition,
Collectors.reducing(BigDecimal.ZERO, Employee::getSalary, BigDecimal::add)
)
));
```
这样可以构建出一个嵌套的 `Map` 结构,支持更复杂的分析需求。
---
阅读全文
相关推荐


















