实战:集合应用
本课是Phase 4的综合实战,通过学生成绩管理系统巩固集合知识。
项目需求
实现一个学生成绩管理系统,支持:
- 添加学生和成绩
- 查询学生成绩
- 按成绩排序
- 统计分析
- 数据导出
数据模型
JAVA
import java.util.ArrayList;
import java.util.List;
public class Student {
private String id;
private String name;
private List<Subject> subjects;
public Student(String id, String name) {
this.id = id;
this.name = name;
this.subjects = new ArrayList<>();
}
public String getId() { return id; }
public String getName() { return name; }
public List<Subject> getSubjects() { return subjects; }
public void addSubject(String name, int score) {
subjects.add(new Subject(name, score));
}
public double getAverage() {
if (subjects.isEmpty()) return 0;
return subjects.stream()
.mapToInt(Subject::getScore)
.average()
.orElse(0);
}
public int getTotal() {
return subjects.stream()
.mapToInt(Subject::getScore)
.sum();
}
@Override
public String toString() {
return name + " (ID:" + id + ", 平均分:" + String.format("%.1f", getAverage()) + ")";
}
}
public class Subject {
private String name;
private int score;
public Subject(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() { return name; }
public int getScore() { return score; }
@Override
public String toString() {
return name + ":" + score;
}
}
管理类
JAVA
import java.util.*;
import java.util.stream.Collectors;
public class GradeManager {
private Map<String, Student> students;
public GradeManager() {
this.students = new LinkedHashMap<>();
}
// 添加学生
public void addStudent(Student student) {
students.put(student.getId(), student);
System.out.println("添加学生:" + student.getName());
}
// 添加成绩
public void addScore(String studentId, String subject, int score) {
Student student = students.get(studentId);
if (student != null) {
student.addSubject(subject, score);
System.out.println(student.getName() + " " + subject + " " + score);
} else {
System.out.println("学生不存在:" + studentId);
}
}
// 查询学生
public Student findStudent(String id) {
return students.get(id);
}
// 按平均分排序
public List<Student> sortByAverage() {
return students.values().stream()
.sorted((a, b) -> Double.compare(b.getAverage(), a.getAverage()))
.collect(Collectors.toList());
}
// 按总分排序
public List<Student> sortByTotal() {
return students.values().stream()
.sorted((a, b) -> Integer.compare(b.getTotal(), a.getTotal()))
.collect(Collectors.toList());
}
// 统计平均分
public double getAverageScore() {
return students.values().stream()
.mapToDouble(Student::getAverage)
.average()
.orElse(0);
}
// 统计最高分
public Student getTopStudent() {
return students.values().stream()
.max(Comparator.comparingDouble(Student::getAverage))
.orElse(null);
}
// 统计最低分
public Student getBottomStudent() {
return students.values().stream()
.min(Comparator.comparingDouble(Student::getAverage))
.orElse(null);
}
// 按等级分组
public Map<String, List<Student>> groupByGrade() {
return students.values().stream()
.collect(Collectors.groupingBy(student -> {
double avg = student.getAverage();
if (avg >= 90) return "优秀";
if (avg >= 80) return "良好";
if (avg >= 70) return "中等";
if (avg >= 60) return "及格";
return "不及格";
}));
}
// 获取所有学生
public List<Student> getAllStudents() {
return new ArrayList<>(students.values());
}
}
主程序
JAVA
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class GradeSystem {
private static GradeManager manager = new GradeManager();
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
// 初始化数据
initData();
// 主循环
int choice;
do {
showMenu();
choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 1: listStudents(); break;
case 2: addScore(); break;
case 3: viewStudent(); break;
case 4: showRanking(); break;
case 5: showStatistics(); break;
case 6: showGroups(); break;
case 0: System.out.println("再见!"); break;
default: System.out.println("无效选择");
}
} while (choice != 0);
scanner.close();
}
private static void initData() {
Student s1 = new Student("S001", "Alice");
s1.addSubject("Java", 95);
s1.addSubject("Python", 88);
s1.addSubject("数据库", 92);
Student s2 = new Student("S002", "Bob");
s2.addSubject("Java", 85);
s2.addSubject("Python", 90);
s2.addSubject("数据库", 78);
Student s3 = new Student("S003", "Charlie");
s3.addSubject("Java", 78);
s3.addSubject("Python", 82);
s3.addSubject("数据库", 88);
manager.addStudent(s1);
manager.addStudent(s2);
manager.addStudent(s3);
}
private static void showMenu() {
System.out.println("\n=== 学生成绩管理系统 ===");
System.out.println("1. 查看所有学生");
System.out.println("2. 添加成绩");
System.out.println("3. 查看学生详情");
System.out.println("4. 成绩排名");
System.out.println("5. 统计分析");
System.out.println("6. 等级分组");
System.out.println("0. 退出");
System.out.print("请选择:");
}
private static void listStudents() {
System.out.println("\n--- 学生列表 ---");
for (Student s : manager.getAllStudents()) {
System.out.println(s);
}
}
private static void addScore() {
System.out.print("请输入学生ID:");
String id = scanner.nextLine();
System.out.print("请输入科目:");
String subject = scanner.nextLine();
System.out.print("请输入分数:");
int score = scanner.nextInt();
scanner.nextLine();
manager.addScore(id, subject, score);
}
private static void viewStudent() {
System.out.print("请输入学生ID:");
String id = scanner.nextLine();
Student student = manager.findStudent(id);
if (student != null) {
System.out.println("\n--- " + student.getName() + "的成绩 ---");
for (Subject s : student.getSubjects()) {
System.out.println(s);
}
System.out.printf("总分:%d,平均分:%.1f%n",
student.getTotal(), student.getAverage());
} else {
System.out.println("学生不存在");
}
}
private static void showRanking() {
System.out.println("\n--- 成绩排名 ---");
List<Student> ranking = manager.sortByAverage();
for (int i = 0; i < ranking.size(); i++) {
Student s = ranking.get(i);
System.out.printf("%d. %s - 平均分:%.1f%n",
i + 1, s.getName(), s.getAverage());
}
}
private static void showStatistics() {
System.out.println("\n=== 统计分析 ===");
System.out.printf("全班平均分:%.1f%n", manager.getAverageScore());
Student top = manager.getTopStudent();
if (top != null) {
System.out.printf("最高分:%s - %.1f%n", top.getName(), top.getAverage());
}
Student bottom = manager.getBottomStudent();
if (bottom != null) {
System.out.printf("最低分:%s - %.1f%n", bottom.getName(), bottom.getAverage());
}
}
private static void showGroups() {
System.out.println("\n=== 等级分组 ===");
Map<String, List<Student>> groups = manager.groupByGrade();
groups.forEach((grade, students) -> {
System.out.println("\n" + grade + "(" + students.size() + "人):");
students.forEach(s ->
System.out.println(" " + s.getName() + " - " + String.format("%.1f", s.getAverage())));
});
}
}
运行示例
TEXT
=== 学生成绩管理系统 ===
1. 查看所有学生
2. 添加成绩
3. 查看学生详情
4. 成绩排名
5. 统计分析
6. 等级分组
0. 退出
请选择:4
--- 成绩排名 ---
1. Alice - 平均分:91.7
2. Bob - 平均分:84.3
3. Charlie - 平均分:82.7
设计要点
| 要点 | 说明 |
|---|---|
| Map存储 | 用Map按ID索引学生 |
| List存储 | 用List存储科目成绩 |
| Stream操作 | 用Stream进行排序、统计、分组 |
| Comparator | 自定义排序规则 |
| Collectors.groupingBy | 按等级分组 |
扩展功能
成绩导出
JAVA
public void exportToFile(String filename) {
try (PrintWriter writer = new PrintWriter(new FileWriter(filename))) {
writer.println("ID,姓名,Java,Python,数据库,总分,平均分");
for (Student s : students.values()) {
writer.printf("%s,%s,%s,%d,%.1f%n",
s.getId(), s.getName(),
s.getSubjects().stream()
.map(sub -> String.valueOf(sub.getScore()))
.collect(Collectors.joining(",")),
s.getTotal(), s.getAverage());
}
System.out.println("导出成功:" + filename);
} catch (IOException e) {
System.out.println("导出失败:" + e.getMessage());
}
}
按科目统计
JAVA
public Map<String, Double> getSubjectAverages() {
Map<String, List<Integer>> subjectScores = new HashMap<>();
for (Student student : students.values()) {
for (Subject subject : student.getSubjects()) {
subjectScores.computeIfAbsent(subject.getName(), k -> new ArrayList<>())
.add(subject.getScore());
}
}
return subjectScores.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().stream().mapToInt(Integer::intValue).average().orElse(0)
));
}
❓ 常见问题
Q 如何支持多班级?
A 用Map<String, GradeManager>存储多个班级。
Q 数据如何持久化?
A 可以使用文件IO或数据库存储。
Q 如何支持导入功能?
A 读取CSV文件,解析后创建Student对象。
📖 小节
- Map按ID索引,List存储科目
- Stream进行排序、统计、分组
- Comparator自定义排序规则
- Collectors.groupingBy实现分组
📝 作业
- 导入功能: 从CSV文件导入学生成绩
- 按科目统计: 统计每科的平均分、最高分、最低分
- 成绩查询: 支持按姓名模糊查询
下一课
下一课我们将进入Phase 5,学习 文件IO,了解文件操作。



