package test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class StudentManageSystem {
/** StudentManager中提供的操作菜单 **/
public static void showMenus() {
String format = " %s\n";
System.out.println("----------------功能菜单------------------");
System.out.printf(format, "0. 退出管理");
System.out.printf(format, "1. 功能菜单");
System.out.printf(format, "2. 显示学生");
System.out.printf(format, "3. 查询学生");
System.out.printf(format, "4. 添加学生");
System.out.printf(format, "5. 删除学生");
System.out.printf(format, "6. 修改学生");
System.out.printf(format, "7. 读取学生");
System.out.printf(format, "8. 保存学生");
System.out.println("-------------------结束------------------");
System.out.println();
}
/** 管理学生信息 **/
public void manageStudents() throws IOException {
Scanner scanner = new Scanner(System.in);
StudentDao sd = new StudentDao();
StudentService ss = new StudentService(sd, scanner);
showMenus();
int op = -1;
while (op != 0) {
System.in.skip(System.in.available());
System.out.print("输入菜单编号: ");
op = scanner.nextInt();
scanner.nextLine(); // 吃掉输入菜单编号后无效的回车字符
try {
switch (op) {
case 0:
break;
case 1:
showMenus();
break;
case 2:
ss.showStudents();
break;
case 3:
ss.findStudents();
break;
case 4:
ss.addStudent();
break;
case 5:
ss.removeStudent();
break;
case 6:
ss.updateStudent();
break;
case 7:
ss.readStudents();
break;
case 8:
ss.saveStudents();
break;
default:
System.out.println("没有提供此项操作\n");
}
} catch (Exception e) {
System.out.println("\t" + e.getMessage() + "\n");
}
}
}
public static void main(String[] args) throws IOException {
StudentManageSystem sm = new StudentManageSystem();
sm.manageStudents();
System.out.println("程序结束");
}
}
/** Service中的很多功能都是委托给Dao对象去完成 **/
class StudentService {
private StudentDao studentDao;
private Scanner scanner;
public StudentService(StudentDao studentDao, Scanner scanner) {
this.studentDao = studentDao;
this.scanner = scanner;
}
// 添加学生
public void addStudent() {
System.out.print("输入学生资料进行添加,格式为id|name|age: "); // name|age
String info = scanner.nextLine();
Student s = Student.buildStudent(info);
if (studentDao.hasStudent(s)) { throw new RuntimeException("此学生信息已经存在"); }
studentDao.addStudent(s);
System.out.println("\t添加成功\n");
}
// 删除学生
public void removeStudent() {
System.out.print("输入学生id进行删除: ");
int id = scanner.nextInt();
Student s = studentDao.findStudent(id);
if (s == null) {
System.out.println("\t查无此学生");
} else {
studentDao.removeStudent(s);
System.out.println("\t已经删除学生: " + s);
}
System.out.println();
}
/** 修改学生信息 **/
public void updateStudent() {
System.out.print("修改学生信息,输入学生id: ");
int id = scanner.nextInt();
Student s = studentDao.findStudent(id);
if (s == null) {
System.out.println("\t查无此学生");
} else {
scanner.nextLine(); // 吃掉回车
System.out.println("\t学生: " + s);
System.out.print("\t输入新的信息,格式为name|age: ");
String line = scanner.nextLine().trim();
if (!line.matches("\\w+\\|\\d+")) {
throw new RuntimeException("输入的修改学生信息格式不对");
}
// 修改已搜索到的学生信息
String[] infos = line.split("\\|");
String name = infos[0];
int age = Integer.parseInt(infos[1]);
s.setName(name);
s.setAge(age);
System.out.println("\t修改完成");
}
System.out.println();
}
/** 输入学生的学号或者姓名进行查找 **/
public void findStudents() {
System.out.print("输入学生ID或者姓名进行查询: ");
String info = scanner.nextLine().trim();
List<Student> ss = new ArrayList<Student>();
// 如果输入的是数字,默认为学号
if (info.matches("\\d+")) {
int id = Integer.parseInt(info);
Student s = studentDao.findStudent(id);
if (s != null) {
ss.add(s);
}
} else {
ss = studentDao.findStudents(info);
}
// 输出查询结果
if (ss.size() == 0) {
System.out.println("查无此学生");
} else {
for (Student s : ss) {
System.out.println("\t" + s);
}
}
System.out.println();
}
/** 显示已经有的学生信息 **/
public void showStudents() {
Set<Student> students = studentDao.getStudents();
if (students.size() == 0) {
System.out.println("\t列表中还没有任何学生");
return;
}
System.out.println("========所有学生信息========");
for (Student s : students) {
System.out.println("\t" + s);
}
System.out.println();
}
public void saveStudents() {
studentDao.saveStudents();
System.out.println("\t保存成功");
}
public void readStudents() {
studentDao.readStudents();
System.out.println("\t读取完成");
}
}
/** 对学生数据进行执久化操作 **/
class StudentDao {
private Set<Student> students;
private String fileName = "students.dat";
public StudentDao() {
students = new TreeSet<Student>(new StudentComparator());
}
/** 添加学生 **/
public void addStudent(Student student) {
students.add(student);
}
/** 删除学生 **/
public void removeStudent(Student student) {
students.remove(student);
}
/** 使用学生的id进行查找 **/
public Student findStudent(int id) {
for (Student s : students) {
if (s.getId() == id) { return s; }
}
return null;
}
/** 使用学生的名字查找进行查找 **/
public List<Student> findStudents(String name) {
List<Student> found = new ArrayList<Student>();
for (Student s : students) {
if (s.getName().equals(name)) {
found.add(s);
}
}
return found;
}
/** 判断学生是否已经存在 **/
public boolean hasStudent(Student s) {
return students.contains(s);
}
/** 返回学生列表的视图,不可修改 **/
public Set<Student> getStudents() {
return Collections.unmodifiableSet(students);
}
/** 把学生信息保存到文件 **/
public void saveStudents() {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(fileName));
oos.writeObject(students);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("保存失败");
} finally {
if (oos != null) {
try {
oos.close();
} catch (Exception e2) {
}
}
}
}
/** 从文件读取学生信息 **/
public void readStudents() {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(fileName));
students = (Set<Student>) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("读取失败");
} finally {
if (ois != null) {
try {
ois.close();
} catch (Exception e2) {
}
}
}
}
}
/** 学生类,可以序列化保存到文件 **/
class Student implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private int age;
private String name;
public Student() {
}
public Student(int id, String name, int age) {
this.id = id;
this.age = age;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// Info format: id|name|age
public static Student buildStudent(String studentInfo) {
if (!studentInfo.matches("\\d+\\|\\w+\\|\\d+")) { throw new RuntimeException(
"The student information's format should be \"id|name|age\" without quote"); }
String[] infos = studentInfo.split("\\|");
int id = Integer.parseInt(infos[0]);
String name = infos[1].trim();
int age = Integer.parseInt(infos[2]);
return new Student(id, name, age);
}
@Override
public int hashCode() {
return id;
}
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != this.getClass()) { return false; }
Student other = (Student) obj;
if (other.id == this.id) { return true; }
return false;
}
@Override
public String toString() {
return String.format("ID:%d, Name:%s, Age:%d", id, name, age);
}
}
// 使用TreeSet时需要的比较器
class StudentComparator implements Comparator<Student>, Serializable {
private static final long serialVersionUID = 1L;
@Override
public int compare(Student s1, Student s2) {
return s1.getId() - s2.getId();
}
}