美文网首页
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