数据结构课程设计——学生成绩系统(写入文件而非数据库)

自己一点点手写的源代码希望给大家一点帮助
对Java的理解还很浅,自己写了之后才觉得一定要多写,这样才可以真正的掌握理解,希望大家看完之后不要all in,要自己认真地理解

import java.io.*;
import java.util.Scanner;
public class StudentScoreManagementSystem {

    class
    Student {//创建一个学生类
        private String studentNumber;//学号
        private String studentName;//姓名
        private int score1;//成绩1
        private int score2;//成绩2
        private int totalScore;//总分

        public Student() {
        }

        public Student(String studentNumber, String studentName, int score1, int score2, int totalScore) {
            this.studentNumber = studentNumber;
            this.studentName = studentName;
            this.score1 = score1;
            this.score2 = score2;
            this.totalScore = totalScore;
        }
        public String getStudentName() {
            return studentName;
        }
        public String getStudentNumber() {
            return studentNumber;
        }
        public int getScore1() {
            return score1;
        }
        public int getScore2() {
            return score2;
        }
        public int getTotalScore() {
            return totalScore;
        }
        public void setStudentName(String studentName) {
            this.studentName = studentName;
        }
        public void setStudentNumber(String studentNumber) {
            this.studentNumber = studentNumber;
        }
        public void setScore1(int score1) {
            this.score1 = score1;
        }
        public void setScore2(int score2) {
            this.score2 = score2;
        }
        public void setTotalScore(int totalScore) {
            this.totalScore = totalScore;
        }
        public String toString() {
            return String.format("学号:%s\t姓名:%s\t成绩一:%d\t成绩二:%d\t总成绩:%d", studentNumber, studentName, score1, score2,
                    totalScore);
        }
        public String toString1(){
            return String.format("%s,%s,%d,%d,%d", studentNumber, studentName, score1, score2,
                    totalScore);
        }
    }

    class Node {//封装学生信息节点
        private Student student;
        public Node next;
        public Node(Student student) {
            this.student = student;
            this.next = null;
        }

        public Node(Student student, Node next) {
            this.student = student;
            this.next = next;
        }

//        public Node(String studentNumber, String studentName, int score1, int score2, int totalScore) {
//            this.student.studentNumber = studentNumber;
//            this.student.studentName = studentName;
//            this.student.score1 = score1;
//            this.student.score2 = score2;
//            this.student.totalScore = totalScore;
//            this.next = null;
//        }

        public Student getStudent() {
            return student;
        }
        public void setStudent(Student student) {
            this.student = student;
        }
    }
    class LinkedList {//封装保存学生信息的链表
        private int size;//链表长度
        private Node head;//头指针指向头结点
        private Node tail;//尾指针 指向链表的最后一个结点
        public LinkedList() {
            size = 0;
            head = tail = null;
        }
        public Node getHead() {//返回头指针
            return head;
        }
        public Node getTail() {//返回尾指针
            return tail;
        }
        public void setHead(Node head) {
            this.head = head;
        }
        public void setTail(Node tail) {
            this.tail = tail;
        }
        public boolean add(Student student) {//向链表中添加学生信息
            if (student == null)
                return false;
            Node n = new Node(student);
            if (head == null) {
                head = n;
                tail = n;
            } else {
                tail.next = n;
                tail = n;
            }
            this.size += 1;
            return true;
        }


        //向链表中删除学生信息
        public boolean remove(Student student) {//删除结点 找到目标结点的前一个结点 prev.next=node.next
            Node prev = null;
            Node node = head;
            while (node != null && !node.getStudent().getStudentNumber().equals(student.getStudentNumber())) {//寻找目标结点
                prev = node;
                node = node.next;
            }
            if (node == null)
                return false;
            if (node.equals(tail)) {
                tail = prev;
                if (prev != null) {
                    prev.next = null;
                }
            }
            Node next = node.next;
            if (prev != null && next != null) {
                prev.next = next;
            } else if (prev != null && next == null) {
                prev.next = null;
            } else if (prev == null && next != null) {
                head = next;
            } else {
                head = null;
            }
            this.size--;
            return true;
        }
        //向链表中插入学生信息
        public boolean insert(Student student, String studentNumber) {//插入结点
            Node dummy = new Node(null);
            dummy.next = head;
            Node prev = dummy;
            Node curr = head;
            while (curr != null && !curr.getStudent().getStudentNumber().equals(studentNumber)) {
                prev = prev.next;
                curr = prev.next;
            }
            if (curr == null)
                return false;

            Node newNode = new Node(student);
            prev.next = newNode;
            newNode.next = curr;
            head = dummy.next;
            size += 1;
            return true;
        }

    }

    private LinkedList studentList;
    private Scanner in = new Scanner(System.in);
    public StudentScoreManagementSystem() {//全局使用的单链表 统一用这个
        studentList = new LinkedList();
    }
    public void readStudentInfo() {
        boolean repeat = false;
        do {
            System.out.println("*********************************************************");
            Student s = new Student();
            boolean correct = true;
            try {
                System.out.println("录入学生信息");
                System.out.println("输入学生学号:");
                s.setStudentNumber(in.nextLine().trim());
                System.out.println("输入学生姓名:");
                s.setStudentName(in.nextLine().trim());
                System.out.println("输入成绩1:");
                s.setScore1(Integer.parseInt(in.nextLine()));
                System.out.println("输入成绩2:");
                s.setScore2(Integer.parseInt(in.nextLine()));
                s.setTotalScore(s.getScore1() + s.getScore2());
                System.out.println(s.toString());
            } catch (Exception e) {
                System.out.println("非法输入");
                correct = false;
            }
            if (correct) {
                studentList.add(s);
                System.out.println("录入成功...是否继续?(Y/N)");
            } else {
                System.out.println("录入失败...是否继续?(Y/N)");
            }
            if (in.nextLine().trim().equalsIgnoreCase("Y")) {
                repeat = true;
            } else
                repeat = false;
        } while (repeat);
        System.out.println("*********************************************************");
        System.out.println();
        System.out.println();
    }
    public void print() {
        System.out.println();
        System.out.println();
        System.out.println("*********************************************************");
        Node curr = studentList.getHead();
        while (curr != null) {
            System.out.println(curr.getStudent().toString());
            curr = curr.next;
        }

        System.out.println("*********************************************************");
        System.out.println();
        System.out.println();
    }
    //按学号查找
    public void findByStudentNumber(String studentNumber) {
        Node n = studentList.getHead();
        while (n != null) {
            if (n.getStudent().getStudentNumber().equals(studentNumber)) {
                System.out.println(String.format("学号为%s的学生信息如下:", studentNumber));//%s 字符串类型 format方法的使用
                System.out.println(n.getStudent().toString());//输出学生信息 如果想要实现文件里的查找 就要添加新的方法
                break;
            }
            n = n.next;
        }
        if (n == null) {
            System.out.println("未找到该学生信息");
        }
    }

    //按姓名查找
    public void findByStudentName(String studentName) {
        Node n = studentList.getHead();
        while (n != null) {
            if (n.getStudent().getStudentName().equals(studentName)) {
                System.out.println(n.getStudent().toString());
                break;
            }
            n = n.next;
        }
        if (n == null) {
            System.out.println("未找到该学生信息");
        }
    }
    public void insertStudent() {
        System.out.println();
        System.out.println();
        String studentNumber = null;
        Student s = new Student();
        boolean correct = true;
        try {
            System.out.println("录入学生信息");
            System.out.println("输入学生学号:");
            s.setStudentNumber(in.nextLine().trim());
            System.out.println("输入学生姓名:");
            s.setStudentName(in.nextLine().trim());
            System.out.println("输入成绩1:");
            s.setScore1(Integer.parseInt(in.nextLine()));
            System.out.println("输入成绩2:");
            s.setScore2(Integer.parseInt(in.nextLine()));
            s.setTotalScore(s.getScore1() + s.getScore2());
            System.out.print("输入要插入位置学生的学号:");
            studentNumber = in.nextLine().trim();
        } catch (Exception e) {
            System.out.println("非法输入");
            correct = false;
        }
        if (correct && studentList.insert(s, studentNumber)) {
            System.out.println("插入成功");
        } else {
            System.out.println("插入失败");
        }
        System.out.println();
        System.out.println();
    }
    public void removeStudent() {
        System.out.println();
        System.out.println();
        System.out.print("输入要删除学生的学号:");
        String studentNumber = in.nextLine().trim();
        Node curr = studentList.getHead();
        while (curr != null) {
            if (curr.getStudent().getStudentNumber().equals(studentNumber)) {
                studentList.remove(curr.getStudent());
                break;
            }
            curr = curr.next;
        }
        System.out.println();
        System.out.println();
    }
    public void find() {//find分为按学号和姓名查找
        int findType = 1;
        System.out.println();
        System.out.println();
        System.out.println("1.按学号查找\t2.按姓名查找\t");
        findType = in.nextInt();
        in.nextLine();//这一步是给下面的输入做准备的
        if (findType == 1) {
            System.out.print("输入要查找学生学号:");
        } else if (findType == 2) {
            System.out.print("输入要查找学生姓名:");
        }
        findStudent(in.nextLine().trim(), findType);//.trim()是去掉字符串两端的空格   这里也是为什么学号要用string的原因 方便
        System.out.println();
        System.out.println();
    }

    public void findStudent(String param, int findType) {//find的实际方法
        switch (findType) {
            case 1:
                findByStudentNumber(param);
                break;
            case 2:
                findByStudentName(param);
                break;
        }
    }
    public void sortStudentListByStudentNumber() {//按学号排序
        Node dummy = new Node(null);
        dummy.next = null;
        Node curr = studentList.getHead();
        Node prev = dummy;//找到指定结点的前一个结点
        while (curr != null) {
            Node next = curr.next;
            curr.next = null;
            prev = dummy;
            while (prev != null && prev.next != null
                    && prev.next.getStudent().getStudentNumber().compareTo(curr.getStudent().getStudentNumber()) < 0) {
                prev = prev.next;
            }
            curr.next = prev.next;
            prev.next = curr;
            studentList.setTail(curr);
            curr = next;
        }
        studentList.setHead(dummy.next);
    }
    public void sortStudent() {
        System.out.println();
        System.out.println();
        int sortType = -1;
        do {
            System.out.println("1.按照学号排序\t2.按照成绩一排序\t3.按照成绩二排序\t4.按照总分排序");
            sortType = in.nextInt();
            in.nextLine();
            if (sortType < 0 || sortType > 4)
                System.out.println("请输入合法序号");
            sortStudentList(sortType);
        } while (sortType < 0 || sortType > 4);
        System.out.println();
        System.out.println();
    }
    public void sortStudentList(int sortType) {
        switch (sortType) {
            case 1:
                sortStudentListByStudentNumber();
                break;
            case 2:
                sortByStudentScore1();
                break;
            case 3:
                sortByStudentScore2();
                break;
            case 4:
                sortByStudentTotalScore();
                break;
        }
    }
    public void sortByStudentScore1() {
        Node dummy = new Node(null);
        dummy.next = null;
        Node curr = studentList.getHead();
        Node prev = dummy;
        while (curr != null) {
            Node next = curr.next;
            curr.next = null;
            prev = dummy;
            while (prev != null && prev.next != null
                    && prev.next.getStudent().getScore1() < curr.getStudent().getScore1()) {
                prev = prev.next;
            }
            curr.next = prev.next;
            prev.next = curr;
            studentList.setTail(curr);
            curr = next;
        }
        studentList.setHead(dummy.next);
    }
    public void sortByStudentScore2() {
        Node dummy = new Node(null);
        dummy.next = null;
        Node curr = studentList.getHead();
        Node prev = dummy;
        while (curr != null) {
            Node next = curr.next;
            curr.next = null;
            prev = dummy;
            while (prev != null && prev.next != null
                    && prev.next.getStudent().getScore2() < curr.getStudent().getScore2()) {
                prev = prev.next;
            }
            curr.next = prev.next;
            prev.next = curr;
            studentList.setTail(curr);
            curr = next;
        }
        studentList.setHead(dummy.next);
    }
    public void sortByStudentTotalScore() {
        Node dummy = new Node(null);
        dummy.next = null;
        Node curr = studentList.getHead();
        Node prev = dummy;
        while (curr != null) {
            Node next = curr.next;
            curr.next = null;
            prev = dummy;
            while (prev != null && prev.next != null
                    && prev.next.getStudent().getTotalScore() < curr.getStudent().getTotalScore()) {
                prev = prev.next;
            }
            curr.next = prev.next;
            prev.next = curr;
            studentList.setTail(curr);
            curr = next;
        }
        studentList.setHead(dummy.next);
    }
    public void summary() {
        int summaryType = -1;
        do {
            System.out.println();
            System.out.println();
            System.out.println("1.统计成绩一平均分\t2.统计成绩二平均分\t3.统计总成绩平均分");
            summaryType = in.nextInt();
            in.nextLine();
            if (summaryType < 1 || summaryType > 3)
                System.out.println("输入合法序号");
        } while (summaryType < 1 || summaryType > 3);
        switch (summaryType) {
            case 1:
                showAverageScore1();
                break;
            case 2:
                showAverageScore2();
                break;
            case 3:
                showAverageTotalScore();
                break;
        }
    }

    public void showAverageScore2() {
        System.out.println();
        System.out.println();
        Node curr = studentList.getHead();
        int sum = 0;
        int count = 0;
        while (curr != null) {
            count += 1;
            sum += curr.getStudent().getScore2();
            System.out
                    .print(String.format("%s:%d\t", curr.getStudent().getStudentName(), curr.getStudent().getScore2()));
            if (count % 5 == 0)
                System.out.println();
            curr = curr.next;
        }
        System.out.println();
        System.out.println(String.format("科目二的平均成绩为:%.3f", sum / (count * 1.0)));
        System.out.println();
        System.out.println();
    }

    public void showAverageTotalScore() {
        System.out.println();
        System.out.println();
        Node curr = studentList.getHead();
        int sum = 0;
        int count = 0;
        while (curr != null) {
            count += 1;
            sum += curr.getStudent().getTotalScore();
            System.out.print(
                    String.format("%s:%d\t", curr.getStudent().getStudentName(), curr.getStudent().getTotalScore()));
            if (count % 5 == 0)
                System.out.println();
            curr = curr.next;
        }
        System.out.println();
        System.out.println(String.format("总成绩的平均值为:%.3f", sum / (count * 1.0)));
        System.out.println();
        System.out.println();
    }
    public void showAverageScore1() {
        System.out.println();
        System.out.println();
        Node curr = studentList.getHead();
        int sum = 0;
        int count = 0;
        while (curr != null) {
            count += 1;
            sum += curr.getStudent().getScore1();
            System.out
                    .print(String.format("%s:%d\t", curr.getStudent().getStudentName(), curr.getStudent().getScore1()));
            if (count % 5 == 0)
                System.out.println();
            curr = curr.next;
        }
        System.out.println();
        System.out.println(String.format("科目一的平均成绩为:%.3f", sum / (count * 1.0)));
        System.out.println();
        System.out.println();
    }
    public void welcome() {
        System.out.println("*********************************************************");
        System.out.println("*                欢迎使用学生成绩管理系统               *");
        System.out.println("*    1.录入学生信息   2.打印学生信息   3.插入学生信息     *");
        System.out.println("*    4.查找学生信息   5.删除学生信息   6.排序学生信息     *");
        System.out.println("*    7.分类统计      8.保存到文件中   9.退出系统         *");
        System.out.println("*********************************************************");
    }
    //保存方法  但是这个方法有一个bug 就是在程序重启后再次写入时还是会覆盖 如何去改变
    //    最后发现bug出现在fileoutstream流这里 当我把这个注释掉之后 就可以正常追加而不会覆盖,我觉得是因为它创建了新的student.txt文件

    public void save() throws IOException{
          File f = new File("student.txt");
//        FileOutputStream fop = new FileOutputStream(f); 这个是字节流
        // 构建FileOutputStream对象,文件不存在会自动新建  应该就是这个东西会创建新的
        FileWriter writer = new FileWriter(f);
        // 如果加 true表示在writer对文件再次写入时,会在该文件的结尾续写,并不会覆盖掉。
        //为了配合load,变成每次重新的覆盖写入
        //FileWriter是字符流

        Node p = studentList.getHead();
        while (p != null) {
            writer.append(p.getStudent().toString1()); // 写入到缓冲区
            writer.append("\r" + "\n");// 换行
            p = p.next;
        }
        writer.close();
        // 关闭写入流,同时会把缓冲区内容写入文件,所以上面的注释掉

//        fop.close();
//        // 关闭输出流,释放系统资源
        System.out.println("保存成功");
    }
    //读取方法  在程序一开始时就默认读取 这样就保证了
    public  void load() throws IOException {
        //    需要做的一个内容就是把string的内容变成student类并添加到链表中
        String filepath = "student.txt";
        BufferedReader reader = new BufferedReader(new FileReader(filepath));
        String temp = reader.readLine();
        while (temp != null) {
            // 解析字符串
            String[] data = temp.split(",");//这个很重要
            String studentNumber=data[0];
            String studentName=data[1];
            int score1 = Integer.parseInt(data[2]);  //用Double.parseDouble()是把括号里面内容变成double类型的。 如果要变成int,则用Integer.parseInt()
            int score2 = Integer.parseInt(data[3]);
            int totalScore = Integer.parseInt(data[4]);
            studentList.add(new Student(studentNumber, studentName, score1,score2,totalScore));
            temp = reader.readLine();
        }
        reader.close();

            }



//    结束方法
    public void out(){
        System.exit(0);
    }
    public void main() throws IOException {
        int choice = 0;
        load();
        while (true) {
            welcome();
            do {
                System.out.print("请选择:");
                choice = Integer.parseInt(in.nextLine().trim());
                if (choice < 1 || choice > 10)
                    System.out.println("请输入合法序号!");
            } while (choice < 1 || choice > 10);

            switch (choice) {
                case 1:
                    readStudentInfo();
                    break;
                case 2:
                    print();
                    break;
                case 3:
                    insertStudent();
                    break;
                case 4:
                    find();
                    break;
                case 5:
                    removeStudent();
                    break;
                case 6:
                    sortStudent();
                    break;
                case 7:
                    summary();
                    break;
                case 8:
                    save();
                    break;
                case 9:
                    out();
                    break;

            }
        }
    }

    public static void main(String[] args) throws Exception {

        StudentScoreManagementSystem SSMS = new StudentScoreManagementSystem();
        SSMS.main();
    }
}

你可能感兴趣的:(数据结构)