stream分组后处理
时间: 2025-03-15 07:07:18 浏览: 16
使用 Java Stream 对分组后的数据进行进一步处理
在 Java 中,Stream
提供了一种强大的方式来操作集合中的数据。当通过 Collectors.groupingBy
进行分组后,可以继续对这些分组的数据执行各种复杂的逻辑运算,比如求和、过滤、排序以及获取特定值等。
以下是几种常见的场景及其实现:
场景一:分组后计算每组的总和
如果希望在分组的基础上计算每组某个字段的总和,可以通过嵌套流的方式完成此任务。例如,在引用中提到的方法[^2]展示了如何利用 Collectors.collectingAndThen
来简化这一过程。
import java.util.*;
import java.util.stream.Collectors;
public class GroupSumExample {
public static void main(String[] args) {
List<ElementComponentDto> list = Arrays.asList(
new ElementComponentDto("A", 10),
new ElementComponentDto("B", 20),
new ElementComponentDto("A", 30)
);
Map<String, Double> result = list.stream()
.collect(Collectors.groupingBy(
ElementComponentDto::getName,
Collectors.summingDouble(ElementComponentDto::getAmount)
));
System.out.println(result);
}
}
class ElementComponentDto {
private String name;
private double amount;
public ElementComponentDto(String name, double amount) {
this.name = name;
this.amount = amount;
}
public String getName() {
return name;
}
public double getAmount() {
return amount;
}
}
上述代码实现了按名称分组并对金额求和的功能。
场景二:分组后筛选每组的最大/最小值
对于需要找到每组内的最大或最小值的情况,可以借助 Collectors.maxBy
或 Collectors.minBy
实现。下面的例子基于引用[^3]展示了一个具体的实现方案。
import java.util.*;
import java.util.stream.Collectors;
public class MaxInGroupExample {
public static void main(String[] args) {
List<NumObj> numList = Arrays.asList(
new NumObj("X", 5),
new NumObj("Y", 10),
new NumObj("X", 7),
new NumObj("Z", 3),
new NumObj("Y", 8)
);
Map<String, Optional<Integer>> resultMap = numList.stream()
.collect(Collectors.groupingBy(
NumObj::getKey,
TreeMap::new,
Collectors.mapping(NumObj::getValue, Collectors.maxBy(Integer::compare))
))
.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().orElse(null)));
resultMap.forEach((key, value) -> System.out.println(key + ": " + value));
}
}
class NumObj {
private String key;
private int value;
public NumObj(String key, int value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public int getValue() {
return value;
}
}
这段代码演示了如何根据键分组并找出每组的最大值。
场景三:解决分组后的无序问题
有时使用 groupingBy
后会遇到顺序丢失的问题。为了保持原始输入的顺序或者指定某种自定义顺序,可以在收集器中引入有序结构如 LinkedHashMap
。这可以从引用[^4]得到启发。
import java.util.*;
import java.util.stream.Collectors;
public class OrderedGroupByExample {
public static void main(String[] args) {
List<MyObject> objects = Arrays.asList(
new MyObject("Alice", 10),
new MyObject("Bob", 20),
new MyObject("Alice", 30),
new MyObject("Charlie", 40)
);
LinkedHashMap<String, List<MyObject>> groupedResult = objects.stream()
.collect(Collectors.groupingBy(
MyObject::getName,
LinkedHashMap::new,
Collectors.toList()
));
groupedResult.forEach((key, values) -> {
System.out.print(key + ": ");
values.forEach(value -> System.out.print(value.getAmount() + ", "));
System.out.println();
});
}
}
class MyObject {
private String name;
private int amount;
public MyObject(String name, int amount) {
this.name = name;
this.amount = amount;
}
public String getName() {
return name;
}
public int getAmount() {
return amount;
}
}
这里采用了 LinkedHashMap
来维护插入顺序。
总结
以上三种方法分别解决了不同类型的业务需求——从简单的数值汇总到复杂的数据提取与排序优化。实际开发过程中可以根据具体的需求灵活组合多种工具链以达到最佳效果。
相关推荐


















