使用groupingBy函数对集合进行分组统计。
使用情景:对学生信息进行统计,统计每个班级男生人数、女生人数。
分组思想如下:
学生类
public class Student {
private String classId;
private String name;
private String sex;
private Integer age;
private Integer height;
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
}
学生统计信息
public class StudentStatistic {
private List<Class> classInfo;
public List<Class> getClassInfo() {
return classInfo;
}
public void setClassInfo(List<Class> classInfo) {
this.classInfo = classInfo;
}
}
public class Class {
private StudentInfo student;
private String classId;
public StudentInfo getStudent() {
return student;
}
public void setStudent(StudentInfo student) {
this.student = student;
}
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
}
public class StudentInfo {
private Integer girl;
private Integer boy;
public Integer getGirl() {
return girl;
}
public void setGirl(Integer girl) {
this.girl = girl;
}
public Integer getBoy() {
return boy;
}
public void setBoy(Integer boy) {
this.boy = boy;
}
}
统计业务逻辑方法
@Component
public class StudentStatisticImpl {
/**
* 根据学生信息获取统计信息
*
* @param students
* 学生列表
*/
public StudentStatistic statisticStudentInfo(List<Student> students) {
// 设置返回列表
StudentStatistic statisticInfo = new StudentStatistic();
List<Class> info = new ArrayList<Class>();
// 信息预处理,当班级ID或性别为null时转为"",原因是后面使用班级ID和性别分组,如果此处为null会报错
students.forEach(std -> {
if (StringUtils.isBlank(std.getClassId())) {
std.setClassId("");
}
if (StringUtils.isBlank(std.getSex())) {
std.setSex("");
}
});
// 学生信息按照班级ID分组,返回map,key为班级ID,value为学生列表
Map<String, List<Student>> student = students.stream().collect(Collectors.groupingBy(Student::getClassId));
if (!CollectionUtils.isEmpty(student)) {
student.forEach((k1, v1) -> {
// 当班级ID不为空时继续统计
if (!StringUtils.isBlank(k1)) {
Class entity = new Class();
StudentInfo statisticInfos = new StudentInfo();
entity.setClassId(k1);
// 按照性别分组
Map<String, List<Student>> studentInfo = v1.stream()
.collect(Collectors.groupingBy(Student::getSex));
if (!CollectionUtils.isEmpty(studentInfo)) {
statisticInfos.setBoy(studentInfo.containsKey("男") ? studentInfo.get("男").size() : 0);
statisticInfos.setGirl(studentInfo.containsKey("女") ? studentInfo.get("女").size() : 0);
}
entity.setStudent(statisticInfos);
info.add(entity);
}
});
statisticInfo.setClassInfo(info);
}
return statisticInfo;
}
}
junit测试
public class TestStatistic {
@InjectMocks
StudentStatisticImpl test;
@Before
public void init() throws DcException {
MockitoAnnotations.initMocks(this);
}
@Test
public void statisticStudentInfo() {
List<Student> students = packagePsgInfo();
StudentStatistic total = test.statisticStudentInfo(students);
System.out.println("--------------starttotal---------------");
System.out.println(JSONObject.toJSON(total));
System.out.println("--------------endtotal---------------");
}
private List<Student> packagePsgInfo() {
List<Student> passengers = new ArrayList<Student>();
Student p1 = new Student();
p1.setClassId("001");
p1.setName("Alice");
p1.setSex("女");
p1.setAge(16);
p1.setHeight(160);
Student p2 = new Student();
p2.setClassId("001");
p2.setName("Kitty");
p2.setSex("女");
p2.setAge(17);
p2.setHeight(161);
Student p3 = new Student();
p3.setClassId("001");
p3.setName("Jim");
p3.setSex("男");
p3.setAge(18);
p3.setHeight(162);
Student p4 = new Student();
p4.setClassId("002");
p4.setName("波比");
p4.setSex("男");
p4.setAge(19);
p4.setHeight(163);
Student p5 = new Student();
p5.setClassId("003");
p5.setName("依依");
p5.setSex("女");
p5.setAge(20);
p5.setHeight(164);
Student p6 = new Student();
p6.setClassId("003");
p6.setName("尔尔");
p6.setSex("男");
p6.setAge(21);
p6.setHeight(164);
Student p7 = new Student();
p7.setClassId("003");
p7.setName("伞伞");
p7.setSex("女");
p7.setAge(22);
p7.setHeight(165);
passengers.add(p1);
passengers.add(p2);
passengers.add(p3);
passengers.add(p4);
passengers.add(p5);
passengers.add(p6);
passengers.add(p7);
return passengers;
}
}
运行测试输出
{
"classInfo": [
{
"classId": "001",
"student": {
"girl": 2,
"boy": 1
}
},
{
"classId": "002",
"student": {
"girl": 0,
"boy": 1
}
},
{
"classId": "003",
"student": {
"girl": 2,
"boy": 1
}
}
]
}