Java实践(三:学生管理系统——List, Set, Map的使用)

58 阅读5分钟

Java集合框架实践项目案例

以下是一个综合使用Java集合框架的学生成绩管理系统案例,涵盖了ArrayList、LinkedList、HashSet、LinkedHashSet、TreeSet、HashMap、LinkedHashMap和TreeMap的使用。

1. 学生实体类

// Student.java
public class Student {
    private String id;
    private String name;
    private int age;
    private String major;
    
    public Student(String id, String name, int age, String major) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.major = major;
    }
    
    // Getters and Setters
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    
    public String getMajor() { return major; }
    public void setMajor(String major) { this.major = major; }
    
    @Override
    public String toString() {
        return "Student{id='" + id + "', name='" + name + "', age=" + age + ", major='" + major + "'}";
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Student student = (Student) obj;
        return id.equals(student.id);
    }
    
    @Override
    public int hashCode() {
        return id.hashCode();
    }
}

2. 成绩实体类

// Grade.java
public class Grade implements Comparable<Grade> {
    private String courseId;
    private String courseName;
    private double score;
    private String semester;
    
    public Grade(String courseId, String courseName, double score, String semester) {
        this.courseId = courseId;
        this.courseName = courseName;
        this.score = score;
        this.semester = semester;
    }
    
    // Getters and Setters
    public String getCourseId() { return courseId; }
    public void setCourseId(String courseId) { this.courseId = courseId; }
    
    public String getCourseName() { return courseName; }
    public void setCourseName(String courseName) { this.courseName = courseName; }
    
    public double getScore() { return score; }
    public void setScore(double score) { this.score = score; }
    
    public String getSemester() { return semester; }
    public void setSemester(String semester) { this.semester = semester; }
    
    @Override
    public String toString() {
        return "Grade{courseId='" + courseId + "', courseName='" + courseName + 
               "', score=" + score + ", semester='" + semester + "'}";
    }
    
    @Override
    public int compareTo(Grade other) {
        // 按分数升序排列
        return Double.compare(this.score, other.score);
    }
}

3. 综合管理系统

// StudentGradeManagementSystem.java
import java.util.*;

public class StudentGradeManagementSystem {
    // 使用ArrayList存储学生列表 - 便于按索引访问
    private List<Student> studentsList = new ArrayList<>();
    
    // 使用LinkedList存储按添加顺序的学生 - 便于频繁插入和删除
    private List<Student> studentsQueue = new LinkedList<>();
    
    // 使用HashSet存储学生ID - 快速查找和去重
    private Set<String> studentIds = new HashSet<>();
    
    // 使用LinkedHashSet存储专业 - 保持插入顺序
    private Set<String> majors = new LinkedHashSet<>();
    
    // 使用TreeSet存储学生 - 按自然排序
    private Set<Student> sortedStudents = new TreeSet<>((s1, s2) -> s1.getName().compareTo(s2.getName()));
    
    // 使用HashMap存储学生ID到成绩列表的映射 - 快速查找
    private Map<String, List<Grade>> studentGrades = new HashMap<>();
    
    // 使用LinkedHashMap存储学期到课程数的映射 - 保持插入顺序
    private Map<String, Integer> semesterCourseCount = new LinkedHashMap<>();
    
    // 使用TreeMap存储课程平均分 - 按课程ID排序
    private Map<String, Double> courseAverageScores = new TreeMap<>();
    
    /**
     * 添加学生
     */
    public void addStudent(Student student) {
        // 添加到ArrayList
        studentsList.add(student);
        
        // 添加到LinkedList
        studentsQueue.add(student);
        
        // 添加到HashSet
        studentIds.add(student.getId());
        
        // 添加到LinkedHashSet
        majors.add(student.getMajor());
        
        // 添加到TreeSet
        sortedStudents.add(student);
        
        System.out.println("学生添加成功: " + student);
    }
    
    /**
     * 为学生添加成绩
     */
    public void addGrade(String studentId, Grade grade) {
        // 检查学生是否存在
        if (!studentIds.contains(studentId)) {
            System.out.println("学生ID不存在: " + studentId);
            return;
        }
        
        // 添加成绩到HashMap
        studentGrades.computeIfAbsent(studentId, k -> new ArrayList<>()).add(grade);
        
        // 更新学期课程数到LinkedHashMap
        semesterCourseCount.merge(grade.getSemester(), 1, Integer::sum);
        
        // 更新课程平均分到TreeMap
        String courseId = grade.getCourseId();
        List<Grade> courseGrades = getAllGradesForCourse(courseId);
        if (!courseGrades.isEmpty()) {
            double average = courseGrades.stream()
                    .mapToDouble(Grade::getScore)
                    .average()
                    .orElse(0.0);
            courseAverageScores.put(courseId, average);
        }
        
        System.out.println("成绩添加成功: " + grade);
    }
    
    /**
     * 获取所有课程的成绩
     */
    private List<Grade> getAllGradesForCourse(String courseId) {
        List<Grade> allGrades = new ArrayList<>();
        for (List<Grade> grades : studentGrades.values()) {
            for (Grade grade : grades) {
                if (grade.getCourseId().equals(courseId)) {
                    allGrades.add(grade);
                }
            }
        }
        return allGrades;
    }
    
    /**
     * 显示所有学生(使用ArrayList)
     */
    public void displayAllStudents() {
        System.out.println("\n=== 所有学生 (ArrayList) ===");
        for (int i = 0; i < studentsList.size(); i++) {
            System.out.println((i + 1) + ". " + studentsList.get(i));
        }
    }
    
    /**
     * 显示最近添加的学生(使用LinkedList)
     */
    public void displayRecentStudents() {
        System.out.println("\n=== 最近添加的学生 (LinkedList) ===");
        // 显示最后3个添加的学生
        int count = 0;
        ListIterator<Student> iterator = ((LinkedList<Student>) studentsQueue).listIterator(studentsQueue.size());
        while (iterator.hasPrevious() && count < 3) {
            System.out.println((count + 1) + ". " + iterator.previous());
            count++;
        }
    }
    
    /**
     * 显示所有专业(使用LinkedHashSet)
     */
    public void displayMajors() {
        System.out.println("\n=== 所有专业 (LinkedHashSet) ===");
        int index = 1;
        for (String major : majors) {
            System.out.println(index + ". " + major);
            index++;
        }
    }
    
    /**
     * 按姓名排序显示学生(使用TreeSet)
     */
    public void displaySortedStudents() {
        System.out.println("\n=== 按姓名排序的学生 (TreeSet) ===");
        int index = 1;
        for (Student student : sortedStudents) {
            System.out.println(index + ". " + student);
            index++;
        }
    }
    
    /**
     * 显示学生成绩(使用HashMap)
     */
    public void displayStudentGrades(String studentId) {
        System.out.println("\n=== 学生成绩 (HashMap) ===");
        List<Grade> grades = studentGrades.get(studentId);
        if (grades != null) {
            System.out.println("学生ID: " + studentId + " 的成绩:");
            for (Grade grade : grades) {
                System.out.println("  " + grade);
            }
        } else {
            System.out.println("未找到学生ID: " + studentId + " 的成绩");
        }
    }
    
    /**
     * 显示学期课程统计(使用LinkedHashMap)
     */
    public void displaySemesterStats() {
        System.out.println("\n=== 学期课程统计 (LinkedHashMap) ===");
        for (Map.Entry<String, Integer> entry : semesterCourseCount.entrySet()) {
            System.out.println("学期: " + entry.getKey() + ", 课程数: " + entry.getValue());
        }
    }
    
    /**
     * 显示课程平均分(使用TreeMap)
     */
    public void displayCourseAverages() {
        System.out.println("\n=== 课程平均分 (TreeMap) ===");
        for (Map.Entry<String, Double> entry : courseAverageScores.entrySet()) {
            System.out.println("课程ID: " + entry.getKey() + ", 平均分: " + String.format("%.2f", entry.getValue()));
        }
    }
    
    /**
     * 演示各种集合的操作性能
     */
    public void demonstratePerformance() {
        System.out.println("\n=== 性能演示 ===");
        
        // ArrayList随机访问
        long startTime = System.nanoTime();
        for (int i = 0; i < 1000 && i < studentsList.size(); i++) {
            Student student = studentsList.get(i);
        }
        long arrayListTime = System.nanoTime() - startTime;
        
        // LinkedList顺序访问
        startTime = System.nanoTime();
        for (Student student : studentsQueue) {
            // 简单遍历
        }
        long linkedListTime = System.nanoTime() - startTime;
        
        // HashSet查找
        startTime = System.nanoTime();
        boolean found = studentIds.contains("S001");
        long hashSetTime = System.nanoTime() - startTime;
        
        System.out.println("ArrayList随机访问耗时: " + arrayListTime + " 纳秒");
        System.out.println("LinkedList顺序访问耗时: " + linkedListTime + " 纳秒");
        System.out.println("HashSet查找耗时: " + hashSetTime + " 纳秒");
    }
    
    /**
     * 主方法 - 演示系统功能
     */
    public static void main(String[] args) {
        StudentGradeManagementSystem system = new StudentGradeManagementSystem();
        
        // 添加学生
        system.addStudent(new Student("S001", "张三", 20, "计算机科学"));
        system.addStudent(new Student("S002", "李四", 21, "软件工程"));
        system.addStudent(new Student("S003", "王五", 19, "数据科学"));
        system.addStudent(new Student("S004", "赵六", 22, "计算机科学"));
        system.addStudent(new Student("S005", "钱七", 20, "人工智能"));
        
        // 添加成绩
        system.addGrade("S001", new Grade("CS101", "Java编程", 85.5, "2023春季"));
        system.addGrade("S001", new Grade("CS102", "数据结构", 92.0, "2023春季"));
        system.addGrade("S002", new Grade("CS101", "Java编程", 78.5, "2023春季"));
        system.addGrade("S002", new Grade("CS103", "算法设计", 88.0, "2023秋季"));
        system.addGrade("S003", new Grade("CS101", "Java编程", 95.0, "2023春季"));
        system.addGrade("S003", new Grade("CS102", "数据结构", 89.5, "2023春季"));
        system.addGrade("S004", new Grade("CS101", "Java编程", 82.0, "2023春季"));
        system.addGrade("S005", new Grade("CS104", "机器学习", 91.5, "2023秋季"));
        
        // 显示各种信息
        system.displayAllStudents();
        system.displayRecentStudents();
        system.displayMajors();
        system.displaySortedStudents();
        system.displayStudentGrades("S001");
        system.displaySemesterStats();
        system.displayCourseAverages();
        system.demonstratePerformance();
    }
}

4. 集合框架使用总结

List接口实现

  • ArrayList: 适用于频繁随机访问元素的场景
  • LinkedList: 适用于频繁插入和删除元素的场景

Set接口实现

  • HashSet: 适用于需要快速查找和去重的场景
  • LinkedHashSet: 适用于需要保持插入顺序的去重场景
  • TreeSet: 适用于需要排序的去重场景

Map接口实现

  • HashMap: 适用于快速键值对查找的场景
  • LinkedHashMap: 适用于需要保持插入顺序的键值对场景
  • TreeMap: 适用于需要按键排序的键值对场景

这个案例展示了Java集合框架在实际项目中的综合应用,每种集合类型都有其特定的使用场景和优势。