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