美文网首页
java中collection框架应用示例:学生选课系统

java中collection框架应用示例:学生选课系统

作者: _Ely | 来源:发表于2018-05-03 15:50 被阅读73次

    java中集合框架概述


    image.png
    • collection集合框架存储对象,有多个接口list,queue,set。他们对应的重要实现类分别是ArrayList,LinkedList,HashSet

    定义类图

    image.png

    public class Course {

    public String id;
    public String name;
    public Course(String id,String name){
        this.id=id;
        this.name=name;
    }
    public Course(){
    }
    

    }

    public class Student {

    public String id;
    public String name;
    
    public Set<Course> courses;
    
    public Student(String id,String name){
        this.id=id;
        this.name=name;
        this.courses=new HashSet<Course>();
    }
    

    }

    使用List接口


    image.png image.png

    /*

    • 备选课程类
      */

    public class ListTest {

    public List courseToSelect;
    
    
    /*
     * 用于存放备选课程的list
     */
    
    
    public ListTest(){
        this.courseToSelect = new ArrayList();
    }
    
    
    /*
     * 用于往coursetoselect中添加备选课程
     */
    public void testAdd(){
        //创建一个课程对象并通过调用add方法,添加到备选课程list中
        Course cr1= new Course("1","数据结构");
        courseToSelect.add(cr1);
        Course temp= (Course) courseToSelect.get(0);
        //System.out.println("添加了课程:"+temp.id+":"+temp.name);
        
        Course cr2 = new Course("2","c语言");
        courseToSelect.add(0, cr2);
        Course temp2=(Course)courseToSelect.get(0);
     //System.out.println("添加了课程:"+temp2.id+":"+temp2.name);
        courseToSelect.add(cr1);
        Course temp0= (Course) courseToSelect.get(2);
        //System.out.println("添加了课程:"+temp0.id+":"+temp0.name);
        
              //以下会抛出数组下标越界异常
               //Course cr3 = new Course("3","cdsfsf");
              //courseToSelect.add(4, cr3);
              Course[] course={new Course("3","离散数学"),new Course("4","汇编语言")};
        courseToSelect.addAll(Arrays.asList(course));
        Course temp3=(Course)courseToSelect.get(3);
        Course temp4=(Course)courseToSelect.get(4);
        
        //System.out.println("添加了两门课程:"+temp3.id+":"+
        //temp3.name+";"+temp4.id+":"+temp4.name);
        
        Course[] course2={new Course("5","高等数学"),new Course("6","大学英语")};
        courseToSelect.addAll(2, Arrays.asList(course2));
        Course temp5=(Course)courseToSelect.get(2);
        Course temp6=(Course)courseToSelect.get(3);
        
        //System.out.println("添加了两门课程:"+temp5.id+":"+
        //temp5.name+";"+temp6.id+":"+temp6.name);
    
    }
    
    
    /*
     * 取得List中的元素的方法
     */
    
    public void testGet(){
        int size =courseToSelect.size();
        System.out.println("有如下课程待选:");
        for(int i=0;i<size;i++){
            Course cr = (Course) courseToSelect.get(i);
            System.out.println("课程:"+cr.id+cr.name);
        }
        
    }
    
    /*
     * 通过迭代器遍历List
     */
    
    public void testIterator(){
        //通过集合的Iterator方法
        Iterator it = courseToSelect.iterator();
        System.out.println("有如下课程待选(通过迭代器访问):");
        while(it.hasNext()){
            Course cr =(Course)it.next();
            System.out.println("课程:"+cr.id+cr.name);
        }
        
    }
    
    /*
     * 通过foreach方法访问集合元素
     */
    public void testForEach(){
        System.out.println("有如下课程待选(通过for each)):");
        for(Object obj:courseToSelect){
            //当元素被存入集合,其类型被忽略为object
            Course cr =(Course)obj;
            System.out.println("课程:"+cr.id+cr.name);
        }
    }
    
    
    /*
     * 修改list中的元素
     */
    public void testModify(){
        courseToSelect.set(4, new Course("7","毛概"));
    }
    
    /*
     * 删除list中的元素
     */
    public void testRemove(){
    //  Course cr =(Course)courseToSelect.get(4);
    //  System.out.println("我是课程"+":"+cr.name+" 我即将被删除");
        //System.out.println("即将删除4位置上的课程!");
        //courseToSelect.remove(4);
        
        
        System.out.println("即将删除4位置和5 位置上的课程!");
        Course[] courses ={(Course) courseToSelect.get(4),(Course) courseToSelect.get(5)};
        courseToSelect.removeAll(Arrays.asList(courses));
        System.out.println("成功珊瑚课程!");
        testForEach();
    }
    
    
    /*
     * 往list中添加一些奇怪的东西
     *
     */
    

    // public void testType(){
    // System.out.println("能否在list");
    // courseToSelect.add("字符串");
    // //不能,用泛型规定添加的元素类型
    // }

    public static void main(String[] args){
        ListTest lt=new ListTest();
        lt.testAdd();
        lt.testForEach();
    
    }
    

    }

    应用泛型管理课程


    image.png

    public class TestGeneric {

    /*
     * 带有泛型---course,的list类型属性
     */
    
    public List<Course> courses;
    
    public TestGeneric(){
        this.courses=new ArrayList<Course>();
        
    }
    
    /*
     * 测试添加
     */
    
    public void testAdd(){
        Course cr1 =new Course("1","大学语文");
        courses.add(cr1);
        //courses.add("能否添加一些奇怪的东西呢???");//当然不能。编译期间检查,不是泛型规定的类型,报错
        //泛型集合中。不能添加 泛型规定的类型及其子类型以外的对象,否则会报错!
        Course cr2 = new Course("2","java basic");
        courses.add(cr2);
    }
    
    /*
     * 测试循环遍历
     */
    public void testForEach(){
        for(Course cr:courses){
            System.out.println(cr.id+":"+cr.name);
        }
    }
    
    /*
     * 泛型集合可以添加泛型的子类型的对象实例
     */
    
    public void testChild(){
        ChildCourse ccr = new ChildCourse();
        ccr.id="3";
        ccr.name="我是子类型的课程对象实例";
        courses.add(ccr);
    }
    
    
    /*
     * 泛型不能使用基本类型
     */
    public void testBasicType(){
        List<Integer> list = new ArrayList<Integer>();
        //注意泛型中的限定类型不能使用基本类型,可以通过使用包装类
        list.add(1);
        System.out.println("基本类型必须使用包装类作为泛型!"+list.get(0));
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TestGeneric tg=new TestGeneric();
        tg.testAdd();
        tg.testForEach();
        tg.testChild();
        tg.testForEach();
        tg.testBasicType();
    }
    

    }

    public class ChildCourse extends Course {
    }

    使用set集合


    image.png
    image.png
    public class SetTest {
    public List<Course> courseToSelect;
    public SetTest(){
            courseToSelect = new ArrayList<Course>();
    }
    
    public void testAdd(){
            //创建一个课程对象并通过调用add方法,添加到备选课程list中
            Course cr1= new Course("1","数据结构");
            courseToSelect.add(cr1);
            
            Course cr2 = new Course("2","c语言");
            courseToSelect.add(0, cr2);
            
            Course[] course={new Course("3","离散数学"),new Course("4","汇编语言")};
            courseToSelect.addAll(Arrays.asList(course));
    
            
            Course[] course2={new Course("5","高等数学"),new Course("6","大学英语")};
            courseToSelect.addAll(2, Arrays.asList(course2));
    
            
    }
    
    public void testForEach(){
        System.out.println("有如下课程待选(通过for each)):");
        for(Object obj:courseToSelect){//当元素被存入集合,其类型被忽略为object
            Course cr =(Course)obj;
            System.out.println("课程:"+cr.id+cr.name);
        }
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        SetTest st = new SetTest();
        st.testAdd();
        st.testForEach();
        
        Student student = new Student("1","Ming");
        System.out.println("欢迎学生: "+student.name+" 选课");
        //创建一个scanner对象接受从键盘输入的课程ID
        Scanner console = new Scanner(System.in);
        
        for(int i=0;i<3;i++){
            System.out.println("请输入课程ID");
            String courseId = console.next();
            for(Course cr :st.courseToSelect){
                if(cr.id.equals(courseId)){
                    student.courses.add(cr);
                    /*
                     * set中,添加某个对象,无论添加多少次
                     * 最终只保留一个该对象(的引用)
                     * 并且,保留的是第一次添加的那一个
                     */
                    //student.courses.add(null);//可以添加空对象,但是没什么意义
            
            }
        }
    }
        st.testForEachforSet(student);
    

    }

    public void testForEachforSet(Student student){
       //打印输出,学生所选的课程!
        System.out.println("共选择了:"+student.courses.size()+"门课程");
        for(Course cr:student.courses){
            System.out.println("选择了课程:"+cr.id+cr.name);
        }
    }
    

    }

    使用map接口


    • map提供映射关系,以键值对存储。


      image.png
    image.png

    代码示例

    public class MapTest {

    /*
     * 用来承装学生类型对象
     */
    public Map<String,Student>students;
    
    /*
     * 在构造器中初始化student属性
     */
    
    public MapTest(){
        this.students = new HashMap<String,Student>();
    }
    
    /*
     * 测试添加:输入学生id,判断是否被占用
     * 若未被占用。则输入学生姓名,创建新的学生对象,并且添加到students中
     */
    public void testPut(){
        //创建一个scanner对象,用来获取输入的学生ID和姓名
        Scanner console = new Scanner(System.in);
        int i = 0;
        while(i<3){
            System.out.println("请输入学生ID");
            String ID =console.next();
            //判断该ID是否被占用
            Student st =students.get(ID);
            if(st==null){
                //提示输入学生姓名
                System.out.println("请输入学生姓名");
                String name = console.next();
                //创建一个新的学生对象
                Student newStudent = new Student(ID,name);
                //通过调用studnets的put方法,添加ID-学生映射
                students.put(ID, newStudent);
                System.out.println("成功添加学生:"+students.get(ID).name);
                i++;
            }else{
                System.out.println("该学生ID已被占用");
                continue;
            }
        }
    }
    
    /*
     * 测试map的keySet方法
     */
    public void testKeySet(){
        //通过keyset方法。返回map中的所有“键”的set集合
        Set<String> keySet = students.keySet();
        //取得stuents的容量
        System.out.println("总共有:"+students.size()+"个学生");
        //遍历keyset,取得每一个键,在调用get方法取得每个键对应的value
        for(String stuId:keySet){
            Student st =students.get(stuId);
            if(st!=null){
                System.out.println("学生:"+st.name);
            }
        }
    }
    
    /*
     * 测试删除map中的映射
     */
    public void testRemove(){
        //获取从键盘输入的待删除学生ID字符串
        Scanner console = new Scanner(System.in);
        while(true){
            //提示输入待删除的学生的ID
            System.out.println("请输入要删除的学生ID!");
            String ID =console.next();
            //判断该ID是都有对应的学生对象
            Student st =students.get(ID);
            if(st==null){
                //提示输入的ID并不存在
                System.out.println("该ID不存在");
                continue;
            }
            students.remove(ID);
            System.out.println("成功删除学生:"+st.name);
            break;
        }
    }
    
    /*
     * 通过entrySet方法来遍历Map
     */
    public void testEntrySet(){
        //通过entrySet该方法,返回map中所有键值对
        Set<Entry<String,Student>> entrySet= students.entrySet();
        for(Entry<String,Student> entry:entrySet){
            System.out.println("取得键:"+entry.getKey());
            System.out.println("对应的值为"+entry.getValue().name);
        }
    }
    
    /*
     * 利用put方法修改map中的已有映射
     */
    public void testModify(){
        //提示输入要修改的学生ID
        System.out.println("请输入要修改的学生ID:");
        //创建scanner对象,获取从键盘上输入的学生ID字符串
        Scanner console = new Scanner(System.in);
        while(true){
            String stuID= console.next();
            //从tsudnets中差好啊该学生ID对应的学生对象
            Student student= students.get(stuID);
            if(student ==null){
                System.out.println("该ID不存在!请重新输入!");
                continue;
            }
            //提示当前对应的学生对象的姓名
            System.out.println("当前该学生的ID:所对应的学生为"+student.name);
            //体术输入新的学生姓名,来修改已有的映射
            System.out.println("请输入新的学生姓名:");
            String name= console.next();
            Student newStudent = new Student(stuID,name);
            students.put(stuID, newStudent);
            System.out.println("修改成功!");
            break;
        }
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MapTest mt = new MapTest();
        mt.testPut();
        mt.testKeySet();
        mt.testRemove();
        mt.testEntrySet();
        mt.testModify();
        mt.testEntrySet();
    }
    

    }

    判断是否包含某元素


    image.png

    利用contains方法

    • 该方法从collection继承来
    • 下面测试list和set的contains方法

    测试set的contains方法

    public void testListContains(){

    //取得备选课程序列的第0个元素
    Course course = courseToSelect.get(0);
    //打印输出courseToSelect是否包含course对象
    System.out.println("取得课程:"+course.name);
    System.out.println("备选课程中是否包含课程:"+course.name+","+courseToSelect.contains(course));
    //包含返回true,不包含返回false
    //创建一个新的课程对象,ID和名称,与course对象完全一样
    Course course2 = new Course(course.id,course.name);
    System.out.println("新创建课程:"+course2.name);
    System.out.println("备选课程中是否包含课程"+course2.name+","+courseToSelect.contains(course2));//**这里是false**
    

    }

    • 所有类都继承自object 有一个equals(Object obj)方法
    • contains(obj)方法实际是遍历其中每一个元素,调用每个元素的equals方法与参数obj比较,所有都不相同,才返回false
    • 通过重写equals方法可以实现通过contains是否包含名称为某个值的课程元素
      在Course类中重写equals方法

    //Override

    public boolean equals(Object obj){
    
        if(this==obj){
            return true;
        }
        if(obj==null)
            return false;
        if(!(obj instanceof Course))
            return false;
        Course course =(Course)obj;
        if(this.name==null){
            if(course.name==null)
                return true;
            else
                return false;
        }else{
            if(this.name.equals(course.name))
                return true;
            else
                return false;
        }
    }
    

    注:该equlas重写方法可以作为一个模板使用

    这之后运行setTest
    其中System.out.println("备选课程中是否包含课程"+course2.name+","+courseToSelect.contains(course2));//
    得到的这里是true,说明equals方法重载成功。

    • object中还有一个方法:hashCode()返回该对象的哈希码的值

    • 当调用contains(obj)的时候,先调用每一个元素的hashcode(),相等再调用equals()。只有认为这两个方法返回的值都相等的时候,才认定hashset包含这个元素

      @Override
      public int hashCode() {

        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
      

      }
      @Override
      public boolean equals(Object obj) {

        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof Course))
            return false;
        Course other = (Course) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
      

      }

    Ecilpse可以自动生成hashcode和equals方法。

    判断元素的索引位置


    //通过indexof方法来获取某元素的索引位置

        if(courseToSelect.contains(course2))
            System.out.println("课程:"+course2.name+"的索引位置为"+courseToSelect.indexOf(course2));
    
    • indexof(java)从0开始遍历,逐个进行equals(java)比较,若返回true,得到元素的索引位置。如果有多个重复元素,返回第一个元素的索引位置
    • lastIndexOf(java)方法与indexof相反,从最后开始遍历
    • 若没有找到该元素,这两个方法都返回-1

    判断map中是否包含指定的key和value值


    /*
     * 测试map中,是否包含某个key值或者某个value值
     */
    public void testContainsKeyOrValue(){
        System.out.println("请输入要查询的学生ID");
        Scanner console = new Scanner(System.in);
        String id = console.next();
        //在map中,用containsKey()方法,来判断是否包含某个Key值
        System.out.println("您输入的学生ID为"+id+",在学生映射表中是否存在:"+students.containsKey(id));
        if(students.containsKey(id))
            System.out.println("对应的学生为:"+students.get(id).name);
        
        System.out.println("请输入要查询的学生姓名:");
        String name = console.next();
        //用containsValue()方法,来判断是否包含某个Value值
        if(students.containsValue(new Student(null,name)))
            System.out.println("在学生映射表中,确实包含学生:"+name);
        else{
            System.out.println("在学生映射表中不存在该学生");
        }
        
    }
    

    【注】这里的查询是否包含学生姓名的时候contain方法仍然调用了hashcode和equals方法,所以要在student类中重载两个方法

    应用collection.sort()实现list排序


    • java.util.collections工具类,提供了许多静态方法,用来操作集合
    • 用collection.sort()实现list排序

    /*

    • 将要完成:
    • 1.通过Collections.sort()方法,对Integer泛型的list进行排序
    • 2.对String泛型的List进行排序
    • 3.对其他类型泛型的list进行排序,以student为例
      */

    public class CollectionsTest {

    /*
     * 1.通过Collections.sort()方法,对Integer泛型的list进行排序
     * 创建一个Integer泛型的list,插入是个100以内不重复的随机数
     * 调用Collections.sort()方法排序
     */
    public void testSort1(){
        List<Integer> integerList = new ArrayList<Integer>();
        //插入是个100以内不重复的随机数
        Random random = new Random();
        Integer k = null;
        for(int i=0;i<10;i++){
            do{
            k = random.nextInt(100);
            }while(integerList.contains(k));
        integerList.add(k);
        System.out.println("成功添加整数:"+k);
        }
        System.out.println("--------排序前-----------");
        for (Integer integer : integerList) {
            System.out.println("元素:"+integer);
        }
        Collections.sort(integerList);
        System.out.println("--------排序后-----------");
        for (Integer integer : integerList) {
            System.out.println("元素:"+integer);
        }
    }
    
    /*
     * 2.对String泛型的List进行排序
     * 创建String泛型的list,添加三个乱序的String
     * 调用sort方法,再次输出排序后的顺序
     */
    
    public void testSort2(){
        List<String> stringList = new ArrayList<String>();
        stringList.add("microsoft");
        stringList.add("google");
        stringList.add("eldasdaf");
        System.out.println("--------排序前-----------");
        for (String string : stringList) {
            System.out.println("元素:"+string);
        }
        Collections.sort(stringList);
        System.out.println("--------排序后-----------");
        for (String string : stringList) {
            System.out.println("元素:"+string);
        }
    }
    
    
    /*
     * 3.对其他类型泛型的list进行排序,以student为例
     */
    public void testSort3(){
        //....
        }
    }
    

    comparable与comparator接口

    image.png
    • comparable默认比较规则,可比较的,实现改接口表示:这个类的示例可以bijou大小。可以进行自然排序。

    public class Student implements Comparable<Student>{

    @Override
    public int compareTo(Student o) {
        // TODO Auto-generated method stub
        return this.id.compareTo(o.id);
    }
    

    public void testSort3(){

        List<Student> studentList = new ArrayList<Student>();
        Random random = new Random();
        studentList.add(new Student(random.nextInt(1000)+"","mike"));
        studentList.add(new Student(random.nextInt(1000)+"","xixo"));
        studentList.add(new Student(random.nextInt(1000)+"","Lan"));
        System.out.println("--------排序前-----------");
        for (Student student : studentList) {
            System.out.println("学生:"+student.id+":"+student.name);
        }
        Collections.sort(studentList);
        System.out.println("--------排序后-----------");
        for (Student student : studentList) {
            System.out.println("学生:"+student.id+":"+student.name);
        }
    }
    
    • comparator 定义临时比较规则

    public class StudentComparator implements Comparator<Student> {

    @Override
    public int compare(Student o1, Student o2) {
        // TODO Auto-generated method stub
        return o1.name.compareTo(o2.name);
    }
    

    }

    public void testSort3(){

        List<Student> studentList = new ArrayList<Student>();
        Random random = new Random();
        studentList.add(new Student(random.nextInt(1000)+"","mike"));
        studentList.add(new Student(random.nextInt(1000)+"","xixo"));
        studentList.add(new Student(random.nextInt(1000)+"","Lan"));
        studentList.add(new Student(10000+"","beyonce"));
                //这里按照姓名排序
        Collections.sort(studentList,new StudentComparator());
        System.out.println("---------按照姓名排序后---------");
        for (Student student : studentList) {
            System.out.println("学生:"+student.id+":"+student.name);
        }
    }
    

    总结

    image.png

    所有类图

    image.png

    github地址:Elylicery
    https://github.com/Elylicery/Code-Exercise/tree/master/imooc-collection-demo

    相关文章

      网友评论

          本文标题:java中collection框架应用示例:学生选课系统

          本文链接:https://www.haomeiwen.com/subject/klwkrftx.html