本文目录导读:

在Java中按字段分组数据,最常用的方法是使用 Stream API 的 Collectors.groupingBy() 方法(Java 8+),以下是几种常见场景的示例:
基础示例:按单个字段分组
import java.util.*;
import java.util.stream.Collectors;
public class GroupByExample {
public static void main(String[] args) {
// 创建数据
List<Student> students = Arrays.asList(
new Student("张三", "A班", 85),
new Student("李四", "B班", 92),
new Student("王五", "A班", 78),
new Student("赵六", "B班", 95),
new Student("钱七", "A班", 88)
);
// 按班级分组
Map<String, List<Student>> groupByClass = students.stream()
.collect(Collectors.groupingBy(Student::getClassName));
// 打印结果
groupByClass.forEach((className, studentList) -> {
System.out.println("班级: " + className);
studentList.forEach(s -> System.out.println(" " + s.getName()));
});
}
}
class Student {
private String name;
private String className;
private int score;
// 构造方法、getter/setter省略
public Student(String name, String className, int score) {
this.name = name;
this.className = className;
this.score = score;
}
public String getName() { return name; }
public String getClassName() { return className; }
public int getScore() { return score; }
}
按多个字段分组
// 创建复合键类
class ClassGradeKey {
private String className;
private String grade;
public ClassGradeKey(String className, String grade) {
this.className = className;
this.grade = grade;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ClassGradeKey that = (ClassGradeKey) o;
return Objects.equals(className, that.className) &&
Objects.equals(grade, that.grade);
}
@Override
public int hashCode() {
return Objects.hash(className, grade);
}
}
// 使用示例
Map<ClassGradeKey, List<Student>> multiGroup = students.stream()
.collect(Collectors.groupingBy(
s -> new ClassGradeKey(s.getClassName(), s.getGrade())
));
分组后统计数据
// 按班级分组,统计每个班的人数
Map<String, Long> countByClass = students.stream()
.collect(Collectors.groupingBy(
Student::getClassName,
Collectors.counting()
));
// 按班级分组,计算平均分
Map<String, Double> avgScoreByClass = students.stream()
.collect(Collectors.groupingBy(
Student::getClassName,
Collectors.averagingInt(Student::getScore)
));
// 按班级分组,找出最高分
Map<String, Optional<Student>> maxScoreByClass = students.stream()
.collect(Collectors.groupingBy(
Student::getClassName,
Collectors.maxBy(Comparator.comparingInt(Student::getScore))
));
分组后转换数据
// 按班级分组,只提取姓名列表
Map<String, List<String>> namesByClass = students.stream()
.collect(Collectors.groupingBy(
Student::getClassName,
Collectors.mapping(Student::getName, Collectors.toList())
));
// 按班级分组,将学生对象转换为分数列表
Map<String, List<Integer>> scoresByClass = students.stream()
.collect(Collectors.groupingBy(
Student::getClassName,
Collectors.mapping(Student::getScore, Collectors.toList())
));
使用传统方式(Java 8之前)
// 传统方式分组
Map<String, List<Student>> groupByClass = new HashMap<>();
for (Student student : students) {
String className = student.getClassName();
groupByClass.computeIfAbsent(className, k -> new ArrayList<>()).add(student);
}
处理复杂的分组场景
// 根据分数范围分组
Map<String, List<Student>> groupByScoreRange = students.stream()
.collect(Collectors.groupingBy(s -> {
int score = s.getScore();
if (score >= 90) return "优秀";
else if (score >= 80) return "良好";
else if (score >= 60) return "及格";
else return "不及格";
}));
// 按多个字段分组(使用字符串拼接作为key)
Map<String, List<Student>> groupByMultipleFields = students.stream()
.collect(Collectors.groupingBy(
s -> s.getClassName() + "-" + s.getGrade()
));
注意事项
-
排序问题:
groupingBy()不保证分组结果的顺序,如果需要有序可以使用groupingBy()的重载版本:// 按班级分组,保持插入顺序 Map<String, List<Student>> groupByClass = students.stream() .collect(Collectors.groupingBy( Student::getClassName, LinkedHashMap::new, // 使用LinkedHashMap保持顺序 Collectors.toList() )); -
null值处理:分组字段为null时,会创建key为null的分组,建议使用
Objects::nonNull过滤。
这些方法适用于大多数按字段分组的需求,选择哪种方式取决于你的具体业务场景。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播