走进Java:实现一个简单的学生管理系统

❀❀❀  大佬求个关注吧~祝您开心每一天  ❀❀❀

目录

一、ArrayList的基本使用

1.1 什么是ArrayList

1.2 ArrayList中的一些常用方法

1.2.1 ArrayList的初始化

无参初始化

 有参构造方式

 1.2.2 元素添加 add()和addAll()

 1.2.3 元素获取get()

1.2.4 元素删除remove()

二、学生管理系统

2.1 学生信息类的定义

2.2 菜单功能功能打印

 2.3 switch控制菜单选择

2.4 while控制菜单循环打印

2.5 学生信息的添加

2.6 学生信息的查找

2.7 学生信息的删除

2.8 学生信息的更新

2.9 打印所有学生信息


今天学习到了Java中的一个小项目,学生管理系统,对于新手来说,从一开始的语法语义学习,跳转到项目学习还是有点吃力的,在学习的过程中我也遇到了一些比较不理解的地方,所以梳理出一篇文章,来记录自己实现学生管理系统的过程,和自己对一些语法语义的理解。

一、ArrayList的基本使用

在学习学生管理系统之前,首先要了解ArrayList的基本使用。已经了解的可以跳过这一部分

1.1 什么是ArrayList

ArrayList是Java中一个非常的集合类,可以把它看作为一种动态数组,并且可以存储任意类型的元素,他有以下一些特点。

  • 动态大小:与传统数组不同,ArrayList的大小能够动态调整。当添加元素使数组容量不足时,ArrayList会自动扩容。
  • 允许存储重复元素:你可以在ArrayList里存储多个相同的元素。
  • 有序集合:元素会按照插入的顺序进行存储,你能够通过索引访问特定位置的元素。
  • 可存储不同类型元素:借助泛型,你既可以指定ArrayList存储特定类型的元素,也可以存储Object类型的元素,从而容纳不同类型的数据。

1.2 ArrayList中的一些常用方法

1.2.1 ArrayList的初始化

ArrayList作为一个类,自然有他的初始化方式,这里介绍两种ArrayList的初始化方式。

无参初始化

在创建ArrayList数组的时候,可以选择无参构造方式进行对象的创建。下方就是源码中的无参构造函数,上面提到了可以把ArrayList看作是一种动态数组,是因为ArrayList的底层就是Object数组,只是ArrayList在使用的时候可以自动的帮我们对元素进行扩容,因此是动态的。

public static void main(String[] args) {
        List<String> list = new ArrayList<>();
    }
 有参构造方式

创建ArrayList的时候还可以传入一些参数,我们只看下方的构造方式。

创建ArrayList对象时,可以传入一个Collection类型的变量,这个Collection类型的变量,其实就是要传入的一个数组,我们把一个已经存在的数组,作为参数传入我们要创建的ArrayList构造方法中,实现值的复制操作。

那么有哪些类可以作为Collection对象传入呢?这是一个实现Collection的树形结构图,我们可以看到Set和List都实现了Collection接口,而我们的ArrayList实现了List接口,所以我们可以把一个已经存在的ArrayList当作参数进行传入。其他的方式大家可以自己验证,只要是实现了Set和List接口的都可以作为参数传递。

public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("aa");
        list1.add("bb");
        list1.add("cc");
        List<String> list2 = new ArrayList<>(list1);
    }

 1.2.2 元素添加 add()和addAll()

首先是add()操作,add用于向ArrayList中添加元素,一次只能添加一个元素。这个操作比较简单,但是需要主义的是,添加的元素必须是在初始化ArrayList是指定的泛型的类型,也就是ArrayList中只可以添加一种类型的元素,不可以添加了String在添加Integer。

public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("aa");
        list1.add("bb");
        list1.add("cc");
        for (String s : list1) {
            System.out.println(s);
        }
    }

然后是addAll()操作,有的时候,我们要把一个ArrayList中的数据,搬到另一个ArrayList中,对于新手来说可能会用到下边的方式。

 public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("aa");
        list1.add("bb");
        list1.add("cc");
        List<String> list2 = new ArrayList<>();
        for (String s : list1) {
            list2.add(s);
        }
    }

但这种方式是多余的,ArrayList提供给我们addAll()方法去解决这个问题。参数同样是Collection类型,也就是说,ArrayList和Set类型的变量都可以作为参数传递。

 1.2.3 元素获取get()

上方写过的代码中,遍历ArrayList的方式是通过增强for循环实现的,那么如何通过普通for循环实现呢?之前说到ArrayList是一个动态数组,既然是数组,那么应该是可以通过下标访问的,但是和普通数组的访问方式不同,ArrayList通过下标访问元素要通过get()方法,get的传参就是元素的索引位置。

public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("aa");
        list1.add("bb");
        list1.add("cc");
        for (int i = 0; i < list1.size(); i++) {
            String s = list1.get(i);
            System.out.println(s);
        }
    }

1.2.4 元素删除remove()

元素删除操作可以通过remove()方法实现,remove方法需要传入一个参数,但是看到下边的方法中,有两个remove方法,这个就是方法重载,如果我们传入的是一个int类型的变量,就会删除对应索引位置的元素,否则的话就寻找ArrayList中的那个元素,然后删掉。

现在我们来试一下。 看看我们要删除aa的方式。

public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("aa");
        list1.add("bb");
        list1.add("cc");
        for (int i = 0; i < list1.size(); i++) {
            String s = list1.get(i);
            System.out.println(s);
        }
        list1.remove("aa");
        //list1.remove(0);
    }

 那么就会有一个问题,如果我们的ArrayList存储的就是int类型的变量呢?那么他会怎样删除呢?这里可以测试一下。

public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.remove(1);
        for (Integer integer : list) {
            System.out.println(integer);
        }
    }

可以看到元素2被删除了,说明删除的是按照索引来的。再测试一下下边的情况。

 public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(4);
        list.remove(4);
        for (Integer integer : list) {
            System.out.println(integer);
        }
    }

这样的情况,并不会删除元素4,而是会报错,因为有方法重载,我们传入的是数字4,是一个int类型的变量,会去寻找索引位置为4的元素,但是我们只有三个元素,所以会有索引越界。

那这样的情况要如何删除呢,要把数字4包装成一个Object类型的变量,Object?如何包装成Objec同类型呢,这里就是Java中的多态了,我们可以传入一个Object的子类,也就是可以传入一个Integer类型的变量。这样就可以了。

public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(4);
        list.remove(new Integer(4));
        for (Integer integer : list) {
            System.out.println(integer);
        }
    }

先简单介绍上边的这些方法,这个是学生管理系统需要的一些方法。

二、学生管理系统

介绍完了ArrayList的基本应用,现在开始着手项目。

2.1 学生信息类的定义

我们需要学生的姓名、学号以及语文数学和英语成绩,作为管理系统的基础。

public class Student {
    // 姓名
    private String name;
    //学号
    private String number;
    // 语文成绩
    private Integer chineseScore;
    // 数学成绩
    private Integer mathScore;
    // 英语成绩
    private Integer englishScore;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public Integer getChineseScore() {
        return chineseScore;
    }

    public void setChineseScore(Integer chineseScore) {
        this.chineseScore = chineseScore;
    }

    public Integer getMathScore() {
        return mathScore;
    }

    public void setMathScore(Integer mathScore) {
        this.mathScore = mathScore;
    }

    public Integer getEnglishScore() {
        return englishScore;
    }

    public void setEnglishScore(Integer englishScore) {
        this.englishScore = englishScore;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", number='" + number + '\'' +
                ", chineseScore=" + chineseScore +
                ", mathScore=" + mathScore +
                ", englishScore=" + englishScore +
                '}';
    }
}

2.2 菜单功能功能打印

对于当前系统,为了便于学习,我们只设置以下几个功能

  1. 学生信息的查找
  2. 学生信息的添加
  3. 学生信息的更新
  4. 学生信息的删除

我们先用输出语句打印一个菜单看看效果。

        System.out.println("┌──────────────────────────┐");
        System.out.println("│      学生信息管理系统       │");
        System.out.println("├──────────────────────────┤");
        System.out.println("│ 1. 学生信息的查找          │");
        System.out.println("│ 2. 学生信息的添加          │");
        System.out.println("│ 3. 学生信息的更新          │");
        System.out.println("│ 4. 学生信息的删除          │");
        System.out.println("│ 0. 退出系统               │");
        System.out.println("└──────────────────────────┘");

看起来效果还不错,就先这样使用。 

不过,当前的菜单代码是在main方法中直接输出的,作为Java学习者,我们更多的要接触面向对象的思想,也就是封装, 对于一些具有独立逻辑的代码,应该将其抽取,作为方法存在。

public static void printMenu(){
        // 打印菜单界面
        System.out.println("┌──────────────────────────┐");
        System.out.println("│      学生信息管理系统       │");
        System.out.println("├──────────────────────────┤");
        System.out.println("│ 1. 学生信息的查找          │");
        System.out.println("│ 2. 学生信息的添加          │");
        System.out.println("│ 3. 学生信息的更新          │");
        System.out.println("│ 4. 学生信息的删除          │");
        System.out.println("│ 0. 退出系统               │");
        System.out.println("└──────────────────────────┘");
    }

 2.3 switch控制菜单选择

有了菜单,我们就要选择菜单中具有的功能选项。

这里就用到了之前学过的siwtch条件分支。

public static void main(String[] args) {
        printMenu();
        int option;
        Scanner sc = new Scanner(System.in);
        System.out.print("请选择要进行的操作:");
        option = sc.nextInt();
        switch (option){
            case 1:
                System.out.println("查找学生信息");
                break;
            case 2:
                System.out.println("添加学生信息");
                break;
            case 3:
                System.out.println("更新学生信息");
                break;
            case 4:
                System.out.println("删除学生信息");
                break;
            case 0:
                System.out.println("退出系统");
                break;
            default:
                break;
        }
    }

到了这一步,已经有了管理系统的雏形了,我们可以根据输入的数组去选择对应的功能。但是现在还有一个问题,当我们选择了某个功能后,对应的方法执行完毕,就会直接让程序结束,这是我们不希望看到的结果,不然每选择一个功能就要退出去程序。

2.4 while控制菜单循环打印

我们只要把输入选项的功能,放在while中就可以解决这个问题,当我们选择功能0的时候,在退出系统,这时候我们可以直接调用System.exit(0)这个方法,退出程序。

public static void main(String[] args) {
        printMenu();
        while(true){
            int option;
            Scanner sc = new Scanner(System.in);
            System.out.print("请选择要进行的操作:");
            option = sc.nextInt();
            switch (option){
                case 1:
                    System.out.println("查找学生信息");
                    break;
                case 2:
                    System.out.println("添加学生信息");
                    break;
                case 3:
                    System.out.println("更新学生信息");
                    break;
                case 4:
                    System.out.println("删除学生信息");
                    break;
                case 5:
                    System.out.println("退出系统");
                    System.exit(0);
                    break;
                default:
                    System.out.println("请输入正确的选项");
                    break;
            }
        }

现在在运行程序,就可以对刚才的菜单进行测试了。

现在就可以进行学生管理系统的编写了。

在上面讲到了,我们对于具有独立功能的代码,要将其抽取出,作为一个方法存在,对于学生的查找、添加、更新和删除操作,我们都应该将其抽取作为独立的方法存在。

2.5 学生信息的添加

为了添加学生的信息,我们需要有一个ArrayList去保存学生的信息,我们需要在main方法中定义出(当然,也可以直接写为静态变量,这样方法就不需要传参了)。

public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
}

在下方的代码中,学生的操作都是围绕这个students列表来的。

我们创建出新的方法addStudent()。这个方法需要两个参数,一个是保存学生信息的集合,另外一个参数是我们要添加的学生的信息。

public static void addStudent(List<Student> students) {
        
    }

至于这里为什么要写第一个参数,第一个参数和我们定义的学生的列表有什么关系,这里简单的介绍一下。

在Java当中,方法传参是值传递,什么是值传递呢?

先介绍一下,List是如何定义的,在Java中,通俗易懂的讲,通过new创建出来的对象,在内存中是有专门的空间来保存的,就像上边我们定义的students列表,它就是在内存中的一块区域保存的。

 看上方的图,在存储区域,我们真正的保存这个列表,而在main区域,我们保存的只是students的地址。 什么是地址呢,就好比一个电话簿,里边记录着很多人的地址,通过地址我们就能找到那个人,这个我们定义的列表有什么关系呢?

这样想,有一个班的同学感情都非常好,大家毕业了,都不想离开教室,因为大家想要一直见面,不想分开。大家都在教室里生活,但是有天发现,教室的位置不够大了,大家在教室里生活了三年,有的人生了娃(假设),老师这时候发话了:“我们的教室位置不够了,我建议大家各回各家,我们把自己的地址记录在每个人的课桌上,这样我们想要见到那个人的时候,就可以根据课桌上的地址找到了”。这样一来,教室的人全都走掉了,大家都在自己家里,空间很大。

main方法和存储区域也是一样的,main方法是存放在栈中的,而对象是存储在堆中的,堆要比栈大得多,所以对象不可以存储在栈中。

这样一来,只要在栈中记录一下列表在堆区的地址就好了,地址占用的空间很小,通过地址就可以顺利的找到列表。

这和值传递有什么关系呢?

值传递,值传递,传递的就是值,但我们在main方法中调用添加学生的方法的时候,会把学生的列表作为参数传递,这里传递的其实是学生列表的地址,addStudent()方法,拿到这个地址后,就可以顺利的找到,学生列表在内存中存储的区域。

知道了这一点,就开始编写学生添加的方法。

 注释很清晰。

    public static void addStudent(List<Student> students) {
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入学生的学号:");
        String number = sc.next();
        // 在我们输入了学生的学号后,还要检查一下是不是已经有这个学生的学号了,我们保证学号唯一
        for (int i = 0; i < students.size(); i++) {
            if (students.get(i).getNumber().equals(number)) {
                // 证明学生已经存在了
                System.out.println("该学生已经存在,请重新尝试\n");
                // 直接返回,因为学生已经存在了,我们不需要在执行方法内的任何逻辑,直接结束这个方法
                return;
            }
        }
        // 能走到这里证明我们输入的学生的学号是没有被存储过的
        System.out.print("请输入学生的姓名:");
        String name = sc.next();
        System.out.print("请输入学生的语文成绩:");
        int chineseScore = sc.nextInt();
        System.out.print("请输入学生的数学成绩:");
        int mathScore = sc.nextInt();
        System.out.print("请输入学生的英语成绩:");
        int englishScore = sc.nextInt();
        // 创建学生对象
        Student student = new Student();
        student.setNumber(number);
        student.setName(name);
        student.setChineseScore(chineseScore);
        student.setMathScore(mathScore);
        student.setEnglishScore(englishScore);
        // 保存学生信息
        students.add(student);
        System.out.println("学生信息添加成功\n");
    }

2.6 学生信息的查找

添加了学生信息的目的,就是为了查找,查找的代码如下。

public static void getStudentInfo(List<Student> students){
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入学生的学号:");
        String number = sc.next();
        for (int i = 0; i < students.size(); i++) {
            if (students.get(i).getNumber().equals(number)) {
                Student student = students.get(i);
                // 说明找到了学生的学号,集合中添加过这个学生
                System.out.println("学生信息如下:");
                System.out.printf("%-10s %-10s %-10s %-10s %-10s\n", "学号", "姓名", "语文成绩", "数学成绩", "英语成绩");
                System.out.printf("%-10s %-10s %-10d %-10d %-10d\n",
                        student.getNumber(), student.getName(), student.getChineseScore(), student.getMathScore(), student.getEnglishScore());
                // 找到了学生信息,直接结束方法就可以
                return;
            }
        }
        // 如果走到了这里,说明遍历完了学生列表,还是没找到学生的信息
        System.out.println("该学生不存在,请重新尝试\n");
    }

2.7 学生信息的删除

public static void deleteStudentInfo(List<Student> students){
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入学生的学号:");
        String number = sc.next();
        // 首先检查一下有没有学生的信息
        for (int i = 0; i < students.size(); i++) {
            if (students.get(i).getNumber().equals(number)) {
                // 说明找到了学生的学号,集合中添加过这个学生
                students.remove(i);
                System.out.println("学生信息删除成功\n");
                return;
            }
        }
        // 如果走到了这里,说明还没有添加这个学生的信息
        System.out.println("该学生不存在,请重新尝试\n");
    }

2.8 学生信息的更新

 public static void updateStudentInfo(List<Student> students){
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入学生的学号:");
        String number = sc.next();
        // 首先检查一下有没有学生的信息
        for (int i = 0; i < students.size(); i++) {
            if (students.get(i).getNumber().equals(number)) {
                Student student = students.get(i);
                // 说明找到了学生的学号,集合中添加过这个学生
                // 先打印一下这个学生的信息
                System.out.println("当前学生信息如下:");
                System.out.printf("%-10s %-10s %-10s %-10s %-10s\n", "学号", "姓名", "语文成绩", "数学成绩", "英语成绩");
                System.out.printf("%-10s %-10s %-10d %-10d %-10d\n",
                        student.getNumber(), student.getName(), student.getChineseScore(), student.getMathScore(), student.getEnglishScore());
                // 然后让用户输入新的学生信息
                System.out.print("请输入学生的姓名:");
                String name = sc.next();
                System.out.print("请输入学生的语文成绩:");
                int chineseScore = sc.nextInt();
                System.out.print("请输入学生的数学成绩:");
                int mathScore = sc.nextInt();
                System.out.print("请输入学生的英语成绩:");
                int englishScore = sc.nextInt();
                // 修改学生信息
                student.setName(name);
                student.setChineseScore(chineseScore);
                student.setMathScore(mathScore);
                student.setEnglishScore(englishScore);
                System.out.println("学生信息修改成功\n");
                return;
            }
        }
        // 如果走到了这里,说明还没有添加这个学生的信息
        System.out.println("该学生不存在,请重新尝试\n");
    }

由于篇幅限制,以后有机会的话,把这个学生管理系统修改为进阶版本的。当然这个版本的代码,还有很多不充分的地方,下期会一一解决。

2.9 打印所有学生信息

大家可以自己加一下这个功能。

 public static void printAllStudentInfo(List<Student> students){
        System.out.println("学生信息如下:");
        System.out.printf("%-10s %-10s %-10s %-10s %-10s\n", "学号", "姓名", "语文成绩", "数学成绩", "英语成绩");
        for (int i = 0; i < students.size(); i++) {
            Student student = students.get(i);
            System.out.printf("%-10s %-10s %-10d %-10d %-10d\n",
                    student.getNumber(), student.getName(), student.getChineseScore(), student.getMathScore(), student.getEnglishScore());
        }
    }

猜你喜欢

转载自blog.csdn.net/2201_76027234/article/details/146457549
今日推荐