在前面的章节中,我们已经学习了Java的基础知识、面向对象编程、高级特性、文件IO、多线程、网络编程和数据库操作等内容。现在,是时候将这些知识应用到实际项目中了。本章我们将从最基础的控制台应用开始,学习如何开发一个完整的Java项目。
控制台应用是最基础的应用类型,它通过命令行界面与用户交互,不需要图形界面。虽然看起来简单,但控制台应用可以实现复杂的功能,而且是学习编程的理想起点。
接下来,我们将开发一个学生信息管理系统,这是一个典型的控制台应用,它能够帮助我们巩固之前学习的知识。
我们的学生信息管理系统需要实现以下功能:
根据需求,我们可以设计以下几个类:
Student
:学生类,包含学生的基本信息StudentManager
:学生管理类,负责学生信息的增删改查FileHandler
:文件处理类,负责数据的读写Main
:主类,包含主菜单和程序入口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;
}
}
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;
}
}
}
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<>(); // 出错时返回空列表
}
}
}
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() + " 名学生");
}
}
}
编译并运行上述代码,你将得到一个功能完整的学生信息管理系统。系统启动后,会显示主菜单,你可以通过输入相应的数字来执行不同的操作。
系统会将学生数据保存到当前目录下的students.dat
文件中,下次启动时会自动加载这些数据。
虽然是控制台应用,但良好的用户界面设计仍然很重要:
控制台应用是学习Java编程的起点,掌握了控制台应用开发后,你可以逐步过渡到其他类型的应用:
无论开发哪种类型的应用,核心业务逻辑的设计思想是相通的,控制台应用中学到的模块化设计、数据处理、异常处理等知识都可以应用到其他类型的应用开发中。
本章我们通过开发一个学生信息管理系统,学习了控制台应用的开发流程和技巧。这个项目综合运用了前面章节学习的Java基础知识、面向对象编程、文件IO等内容,是一个很好的实践项目。
控制台应用虽然简单,但它是学习编程的重要基础,掌握了控制台应用开发,你就具备了开发其他类型应用的基础能力。在接下来的章节中,我们将学习如何开发桌面应用、Web应用等更复杂的应用类型。