零基础学Java——第十一章:实战项目 - 控制台应用开发

发布于:2025-05-13 ⋅ 阅读:(16) ⋅ 点赞:(0)

第十一章:实战项目 - 控制台应用开发

在前面的章节中,我们已经学习了Java的基础知识、面向对象编程、高级特性、文件IO、多线程、网络编程和数据库操作等内容。现在,是时候将这些知识应用到实际项目中了。本章我们将从最基础的控制台应用开始,学习如何开发一个完整的Java项目。

1. 控制台应用概述

控制台应用是最基础的应用类型,它通过命令行界面与用户交互,不需要图形界面。虽然看起来简单,但控制台应用可以实现复杂的功能,而且是学习编程的理想起点。

1.1 控制台应用的特点

  • 简单直接:无需复杂的UI设计,专注于核心功能实现
  • 开发效率高:开发周期短,适合快速验证想法
  • 资源消耗低:运行时占用系统资源少
  • 适合后台服务:很多服务器端程序都是以控制台形式运行的
  • 调试方便:输出结果直观,便于调试

1.2 常见的控制台应用类型

  • 文本处理工具
  • 数据分析程序
  • 简单游戏(如猜数字、文字冒险等)
  • 系统工具(如文件管理器、备份工具等)
  • 数据库管理工具

2. 项目实战:学生信息管理系统

接下来,我们将开发一个学生信息管理系统,这是一个典型的控制台应用,它能够帮助我们巩固之前学习的知识。

2.1 需求分析

我们的学生信息管理系统需要实现以下功能:

  1. 添加学生信息(学号、姓名、年龄、成绩等)
  2. 删除学生信息
  3. 修改学生信息
  4. 查询学生信息(按学号、姓名等条件查询)
  5. 显示所有学生信息
  6. 数据持久化(保存到文件)
  7. 数据加载(从文件读取)

2.2 系统设计

根据需求,我们可以设计以下几个类:

  1. Student:学生类,包含学生的基本信息
  2. StudentManager:学生管理类,负责学生信息的增删改查
  3. FileHandler:文件处理类,负责数据的读写
  4. Main:主类,包含主菜单和程序入口

2.3 代码实现

2.3.1 Student类
package studentmanager;

import java.io.Serializable;

public class Student implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private String id;          // 学号
    private String name;        // 姓名
    private int age;            // 年龄
    private double score;       // 成绩
    
    // 构造方法
    public Student(String id, String name, int age, double score) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.score = score;
    }
    
    // getter和setter方法
    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 double getScore() {
        return score;
    }
    
    public void setScore(double score) {
        this.score = score;
    }
    
    @Override
    public String toString() {
        return "学号: " + id + ", 姓名: " + name + ", 年龄: " + age + ", 成绩: " + score;
    }
}
2.3.2 StudentManager类
package studentmanager;

import java.util.ArrayList;
import java.util.List;

public class StudentManager {
    private List<Student> students;
    private FileHandler fileHandler;
    
    public StudentManager() {
        students = new ArrayList<>();
        fileHandler = new FileHandler();
        // 尝试从文件加载数据
        loadData();
    }
    
    // 添加学生
    public boolean addStudent(Student student) {
        // 检查学号是否已存在
        for (Student s : students) {
            if (s.getId().equals(student.getId())) {
                return false; // 学号已存在,添加失败
            }
        }
        students.add(student);
        saveData(); // 保存数据
        return true;
    }
    
    // 删除学生
    public boolean deleteStudent(String id) {
        for (int i = 0; i < students.size(); i++) {
            if (students.get(i).getId().equals(id)) {
                students.remove(i);
                saveData(); // 保存数据
                return true;
            }
        }
        return false; // 未找到该学生
    }
    
    // 修改学生信息
    public boolean updateStudent(String id, String name, int age, double score) {
        for (Student student : students) {
            if (student.getId().equals(id)) {
                student.setName(name);
                student.setAge(age);
                student.setScore(score);
                saveData(); // 保存数据
                return true;
            }
        }
        return false; // 未找到该学生
    }
    
    // 按学号查询学生
    public Student findStudentById(String id) {
        for (Student student : students) {
            if (student.getId().equals(id)) {
                return student;
            }
        }
        return null; // 未找到该学生
    }
    
    // 按姓名查询学生
    public List<Student> findStudentsByName(String name) {
        List<Student> result = new ArrayList<>();
        for (Student student : students) {
            if (student.getName().contains(name)) {
                result.add(student);
            }
        }
        return result;
    }
    
    // 获取所有学生
    public List<Student> getAllStudents() {
        return new ArrayList<>(students); // 返回副本,避免外部修改
    }
    
    // 保存数据到文件
    private void saveData() {
        fileHandler.saveStudents(students);
    }
    
    // 从文件加载数据
    private void loadData() {
        List<Student> loadedStudents = fileHandler.loadStudents();
        if (loadedStudents != null) {
            students = loadedStudents;
        }
    }
}
2.3.3 FileHandler类
package studentmanager;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class FileHandler {
    private static final String FILE_NAME = "students.dat";
    
    // 保存学生数据到文件
    public void saveStudents(List<Student> students) {
        try (ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream(FILE_NAME))) {
            oos.writeObject(students);
            System.out.println("数据已成功保存到文件");
        } catch (IOException e) {
            System.out.println("保存数据时出错: " + e.getMessage());
        }
    }
    
    // 从文件加载学生数据
    @SuppressWarnings("unchecked")
    public List<Student> loadStudents() {
        File file = new File(FILE_NAME);
        if (!file.exists()) {
            return new ArrayList<>(); // 文件不存在,返回空列表
        }
        
        try (ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream(FILE_NAME))) {
            List<Student> students = (List<Student>) ois.readObject();
            System.out.println("数据已成功从文件加载");
            return students;
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("加载数据时出错: " + e.getMessage());
            return new ArrayList<>(); // 出错时返回空列表
        }
    }
}
2.3.4 Main类
package studentmanager;

import java.util.List;
import java.util.Scanner;

public class Main {
    private static StudentManager manager = new StudentManager();
    private static Scanner scanner = new Scanner(System.in);
    
    public static void main(String[] args) {
        boolean running = true;
        
        System.out.println("欢迎使用学生信息管理系统");
        
        while (running) {
            showMenu();
            int choice = getChoice();
            
            switch (choice) {
                case 1:
                    addStudent();
                    break;
                case 2:
                    deleteStudent();
                    break;
                case 3:
                    updateStudent();
                    break;
                case 4:
                    findStudent();
                    break;
                case 5:
                    showAllStudents();
                    break;
                case 0:
                    running = false;
                    System.out.println("感谢使用学生信息管理系统,再见!");
                    break;
                default:
                    System.out.println("无效的选择,请重新输入");
            }
        }
        
        scanner.close();
    }
    
    // 显示主菜单
    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("0. 退出系统");
        System.out.print("请输入您的选择: ");
    }
    
    // 获取用户输入的选择
    private static int getChoice() {
        try {
            return Integer.parseInt(scanner.nextLine());
        } catch (NumberFormatException e) {
            return -1; // 输入无效
        }
    }
    
    // 添加学生
    private static void addStudent() {
        System.out.println("\n----- 添加学生 -----");
        
        System.out.print("请输入学号: ");
        String id = scanner.nextLine();
        
        System.out.print("请输入姓名: ");
        String name = scanner.nextLine();
        
        int age = 0;
        boolean validAge = false;
        while (!validAge) {
            System.out.print("请输入年龄: ");
            try {
                age = Integer.parseInt(scanner.nextLine());
                validAge = true;
            } catch (NumberFormatException e) {
                System.out.println("年龄必须是整数,请重新输入");
            }
        }
        
        double score = 0.0;
        boolean validScore = false;
        while (!validScore) {
            System.out.print("请输入成绩: ");
            try {
                score = Double.parseDouble(scanner.nextLine());
                validScore = true;
            } catch (NumberFormatException e) {
                System.out.println("成绩必须是数字,请重新输入");
            }
        }
        
        Student student = new Student(id, name, age, score);
        boolean success = manager.addStudent(student);
        
        if (success) {
            System.out.println("学生添加成功!");
        } else {
            System.out.println("添加失败,该学号已存在");
        }
    }
    
    // 删除学生
    private static void deleteStudent() {
        System.out.println("\n----- 删除学生 -----");
        
        System.out.print("请输入要删除的学生学号: ");
        String id = scanner.nextLine();
        
        boolean success = manager.deleteStudent(id);
        
        if (success) {
            System.out.println("学生删除成功!");
        } else {
            System.out.println("删除失败,未找到该学号的学生");
        }
    }
    
    // 修改学生信息
    private static void updateStudent() {
        System.out.println("\n----- 修改学生信息 -----");
        
        System.out.print("请输入要修改的学生学号: ");
        String id = scanner.nextLine();
        
        // 先查询该学生是否存在
        Student student = manager.findStudentById(id);
        
        if (student == null) {
            System.out.println("未找到该学号的学生");
            return;
        }
        
        System.out.println("当前学生信息: " + student);
        
        System.out.print("请输入新的姓名(直接回车保持不变): ");
        String name = scanner.nextLine();
        if (name.isEmpty()) {
            name = student.getName();
        }
        
        int age = student.getAge();
        System.out.print("请输入新的年龄(直接回车保持不变): ");
        String ageStr = scanner.nextLine();
        if (!ageStr.isEmpty()) {
            try {
                age = Integer.parseInt(ageStr);
            } catch (NumberFormatException e) {
                System.out.println("年龄格式无效,保持原值");
            }
        }
        
        double score = student.getScore();
        System.out.print("请输入新的成绩(直接回车保持不变): ");
        String scoreStr = scanner.nextLine();
        if (!scoreStr.isEmpty()) {
            try {
                score = Double.parseDouble(scoreStr);
            } catch (NumberFormatException e) {
                System.out.println("成绩格式无效,保持原值");
            }
        }
        
        boolean success = manager.updateStudent(id, name, age, score);
        
        if (success) {
            System.out.println("学生信息修改成功!");
        } else {
            System.out.println("修改失败");
        }
    }
    
    // 查询学生信息
    private static void findStudent() {
        System.out.println("\n----- 查询学生信息 -----");
        System.out.println("1. 按学号查询");
        System.out.println("2. 按姓名查询");
        System.out.print("请选择查询方式: ");
        
        int choice = getChoice();
        
        switch (choice) {
            case 1:
                findStudentById();
                break;
            case 2:
                findStudentsByName();
                break;
            default:
                System.out.println("无效的选择");
        }
    }
    
    // 按学号查询学生
    private static void findStudentById() {
        System.out.print("请输入学号: ");
        String id = scanner.nextLine();
        
        Student student = manager.findStudentById(id);
        
        if (student != null) {
            System.out.println("查询结果: " + student);
        } else {
            System.out.println("未找到该学号的学生");
        }
    }
    
    // 按姓名查询学生
    private static void findStudentsByName() {
        System.out.print("请输入姓名(支持模糊查询): ");
        String name = scanner.nextLine();
        
        List<Student> students = manager.findStudentsByName(name);
        
        if (students.isEmpty()) {
            System.out.println("未找到匹配的学生");
        } else {
            System.out.println("查询结果:");
            for (Student student : students) {
                System.out.println(student);
            }
            System.out.println("共找到 " + students.size() + " 名学生");
        }
    }
    
    // 显示所有学生
    private static void showAllStudents() {
        System.out.println("\n----- 所有学生信息 -----");
        
        List<Student> students = manager.getAllStudents();
        
        if (students.isEmpty()) {
            System.out.println("暂无学生信息");
        } else {
            for (Student student : students) {
                System.out.println(student);
            }
            System.out.println("共有 " + students.size() + " 名学生");
        }
    }
}

2.4 运行与测试

编译并运行上述代码,你将得到一个功能完整的学生信息管理系统。系统启动后,会显示主菜单,你可以通过输入相应的数字来执行不同的操作。

系统会将学生数据保存到当前目录下的students.dat文件中,下次启动时会自动加载这些数据。

2.5 项目扩展思路

  1. 添加更多学生属性:如性别、班级、联系方式等
  2. 实现成绩管理:添加多门课程的成绩记录和统计功能
  3. 添加用户认证:实现登录功能,区分管理员和普通用户权限
  4. 优化数据存储:使用数据库替代文件存储,提高数据管理能力
  5. 添加数据导出功能:支持将数据导出为CSV或Excel格式
  6. 添加数据统计分析:如成绩分布、平均分计算等

3. 控制台应用开发的最佳实践

3.1 用户界面设计

虽然是控制台应用,但良好的用户界面设计仍然很重要:

  • 清晰的菜单结构:主菜单和子菜单层次分明
  • 友好的提示信息:每一步操作都有明确的提示
  • 错误处理:对用户输入进行验证,给出友好的错误提示
  • 操作确认:对重要操作(如删除)进行确认
  • 分页显示:数据量大时分页显示,避免信息过多

3.2 代码组织

  • 模块化设计:将不同功能划分为不同的类和方法
  • 单一职责原则:每个类只负责一项功能
  • 封装实现细节:隐藏内部实现,只暴露必要的接口
  • 注释完善:关键代码添加注释,提高可读性
  • 异常处理:合理处理可能出现的异常情况

3.3 性能优化

  • 减少IO操作:频繁的文件读写会影响性能
  • 使用合适的数据结构:根据需求选择合适的集合类
  • 避免不必要的对象创建:重用对象,减少垃圾回收压力
  • 延迟加载:只在需要时才加载数据
  • 批量处理:将多个操作合并处理,减少交互次数

4. 从控制台应用到其他类型应用的过渡

控制台应用是学习Java编程的起点,掌握了控制台应用开发后,你可以逐步过渡到其他类型的应用:

  1. 桌面应用:使用Swing或JavaFX开发图形界面应用
  2. Web应用:使用Servlet、JSP或Spring框架开发Web应用
  3. 移动应用:使用Android开发移动应用
  4. 微服务:使用Spring Boot、Spring Cloud开发微服务应用

无论开发哪种类型的应用,核心业务逻辑的设计思想是相通的,控制台应用中学到的模块化设计、数据处理、异常处理等知识都可以应用到其他类型的应用开发中。

5. 总结

本章我们通过开发一个学生信息管理系统,学习了控制台应用的开发流程和技巧。这个项目综合运用了前面章节学习的Java基础知识、面向对象编程、文件IO等内容,是一个很好的实践项目。

控制台应用虽然简单,但它是学习编程的重要基础,掌握了控制台应用开发,你就具备了开发其他类型应用的基础能力。在接下来的章节中,我们将学习如何开发桌面应用、Web应用等更复杂的应用类型。

6. 练习题

  1. 在学生信息管理系统的基础上,添加学生成绩排序功能(按成绩从高到低排序)。
  2. 扩展系统,添加班级管理功能,每个学生属于一个班级,可以按班级查询学生。
  3. 实现一个简单的文本编辑器,支持创建、打开、编辑和保存文本文件。
  4. 开发一个简单的通讯录程序,支持联系人的增删改查和数据持久化。
  5. 设计一个简单的银行账户管理系统,支持开户、存款、取款、转账和查询余额等功能。

7. 参考资源