Practice: Collection Applications

This lesson is the hands-on practice for Phase 4, consolidating collection knowledge through a student grade management system.

Project Requirements

Implement a student grade management system that supports:

Data Model

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 + ", Avg:" + 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;
    }
}

Manager Class

JAVA
import java.util.*;
import java.util.stream.Collectors;

public class GradeManager {
    private Map<String, Student> students;
    
    public GradeManager() {
        this.students = new LinkedHashMap<>();
    }
    
    // Add student
    public void addStudent(Student student) {
        students.put(student.getId(), student);
        System.out.println("Added student: " + student.getName());
    }
    
    // Add grade
    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("Student not found: " + studentId);
        }
    }
    
    // Find student
    public Student findStudent(String id) {
        return students.get(id);
    }
    
    // Sort by average
    public List<Student> sortByAverage() {
        return students.values().stream()
            .sorted((a, b) -> Double.compare(b.getAverage(), a.getAverage()))
            .collect(Collectors.toList());
    }
    
    // Sort by total
    public List<Student> sortByTotal() {
        return students.values().stream()
            .sorted((a, b) -> Integer.compare(b.getTotal(), a.getTotal()))
            .collect(Collectors.toList());
    }
    
    // Calculate average score
    public double getAverageScore() {
        return students.values().stream()
            .mapToDouble(Student::getAverage)
            .average()
            .orElse(0);
    }
    
    // Get top student
    public Student getTopStudent() {
        return students.values().stream()
            .max(Comparator.comparingDouble(Student::getAverage))
            .orElse(null);
    }
    
    // Get bottom student
    public Student getBottomStudent() {
        return students.values().stream()
            .min(Comparator.comparingDouble(Student::getAverage))
            .orElse(null);
    }
    
    // Group by grade
    public Map<String, List<Student>> groupByGrade() {
        return students.values().stream()
            .collect(Collectors.groupingBy(student -> {
                double avg = student.getAverage();
                if (avg >= 90) return "Excellent";
                if (avg >= 80) return "Good";
                if (avg >= 70) return "Average";
                if (avg >= 60) return "Pass";
                return "Fail";
            }));
    }
    
    // Get all students
    public List<Student> getAllStudents() {
        return new ArrayList<>(students.values());
    }
}

Main Program

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) {
        // Initialize data
        initData();
        
        // Main loop
        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("Goodbye!"); break;
                default: System.out.println("Invalid choice");
            }
        } 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("Database", 92);
        
        Student s2 = new Student("S002", "Bob");
        s2.addSubject("Java", 85);
        s2.addSubject("Python", 90);
        s2.addSubject("Database", 78);
        
        Student s3 = new Student("S003", "Charlie");
        s3.addSubject("Java", 78);
        s3.addSubject("Python", 82);
        s3.addSubject("Database", 88);
        
        manager.addStudent(s1);
        manager.addStudent(s2);
        manager.addStudent(s3);
    }
    
    private static void showMenu() {
        System.out.println("\n=== Student Grade Management System ===");
        System.out.println("1. View all students");
        System.out.println("2. Add grade");
        System.out.println("3. View student details");
        System.out.println("4. Grade ranking");
        System.out.println("5. Statistics");
        System.out.println("6. Grade groups");
        System.out.println("0. Exit");
        System.out.print("Enter choice: ");
    }
    
    private static void listStudents() {
        System.out.println("\n--- Student List ---");
        for (Student s : manager.getAllStudents()) {
            System.out.println(s);
        }
    }
    
    private static void addScore() {
        System.out.print("Enter student ID: ");
        String id = scanner.nextLine();
        System.out.print("Enter subject: ");
        String subject = scanner.nextLine();
        System.out.print("Enter score: ");
        int score = scanner.nextInt();
        scanner.nextLine();
        
        manager.addScore(id, subject, score);
    }
    
    private static void viewStudent() {
        System.out.print("Enter student ID: ");
        String id = scanner.nextLine();
        
        Student student = manager.findStudent(id);
        if (student != null) {
            System.out.println("\n--- " + student.getName() + "'s Grades ---");
            for (Subject s : student.getSubjects()) {
                System.out.println(s);
            }
            System.out.printf("Total: %d, Average: %.1f%n", 
                student.getTotal(), student.getAverage());
        } else {
            System.out.println("Student not found");
        }
    }
    
    private static void showRanking() {
        System.out.println("\n--- Grade Ranking ---");
        List<Student> ranking = manager.sortByAverage();
        for (int i = 0; i < ranking.size(); i++) {
            Student s = ranking.get(i);
            System.out.printf("%d. %s - Average: %.1f%n", 
                i + 1, s.getName(), s.getAverage());
        }
    }
    
    private static void showStatistics() {
        System.out.println("\n=== Statistics ===");
        System.out.printf("Class average: %.1f%n", manager.getAverageScore());
        
        Student top = manager.getTopStudent();
        if (top != null) {
            System.out.printf("Highest: %s - %.1f%n", top.getName(), top.getAverage());
        }
        
        Student bottom = manager.getBottomStudent();
        if (bottom != null) {
            System.out.printf("Lowest: %s - %.1f%n", bottom.getName(), bottom.getAverage());
        }
    }
    
    private static void showGroups() {
        System.out.println("\n=== Grade Groups ===");
        Map<String, List<Student>> groups = manager.groupByGrade();
        
        groups.forEach((grade, students) -> {
            System.out.println("\n" + grade + " (" + students.size() + " students):");
            students.forEach(s -> 
                System.out.println("  " + s.getName() + " - " + String.format("%.1f", s.getAverage())));
        });
    }
}

Example Output

TEXT
=== Student Grade Management System ===
1. View all students
2. Add grade
3. View student details
4. Grade ranking
5. Statistics
6. Grade groups
0. Exit
Enter choice: 4

--- Grade Ranking ---
1. Alice - Average: 91.7
2. Bob - Average: 84.3
3. Charlie - Average: 82.7

Design Highlights

Aspect Description
Map storage Map indexes students by ID
List storage List stores subject grades
Stream operations Stream for sorting, statistics, grouping
Comparator Custom sorting rules
Collectors.groupingBy Group by grade level

Extended Features

Grade Export

JAVA
public void exportToFile(String filename) {
    try (PrintWriter writer = new PrintWriter(new FileWriter(filename))) {
        writer.println("ID,Name,Java,Python,Database,Total,Average");
        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("Export successful: " + filename);
    } catch (IOException e) {
        System.out.println("Export failed: " + e.getMessage());
    }
}

Statistics by Subject

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)
        ));
}

❓ Frequently Asked Questions

Q How to support multiple classes?
A Use Map<String, GradeManager> to store multiple classes.
Q How to persist data?
A Use file IO or database storage.
Q How to support import functionality?
A Read CSV files and create Student objects after parsing.

📖 Summary

📝 Exercises

  1. Import: Import student grades from CSV file
  2. Subject statistics: Calculate average, highest, lowest for each subject
  3. Grade search: Support fuzzy search by student name

Next Lesson

In the next lesson, we'll move to Phase 5 and learn about File IO — file operations.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏