zoukankan      html  css  js  c++  java
  • Java 之集合框架 上(9)

    Java 中的集合框架

    如果一个类中存在很多相同类型的属性。

    例如:学生类

    学生可以选课,因此存在很多课程类型的属性。但是每个学生选择的课程的种类和数量是不一样的。

    如果将每一个课程类型的属性都列到课程类中,这样就很难定义学生类了。

    这时我们可以利用容器,把所有的课程类型的属性都加入到容器中,再将这个容器整体作为学生类的一个属性

    上面所说的容器就是Java中的集合。

    集合的概念:

    现实生活中:很多的事物凑在一起。例如 超市中的购物车是商品的集合、军队是军人的集合

    数学中的集合:具有共同属性的事物的总体。例如:有理数 和 整数

    Java中的集合类:是一种工具类,就像是一个容器,储存任意数量的有共同属性的对象。

     

    集合的作用:

    1 在集合的内部,对数据进行组织

    2 简单而快速的搜索大量的条目

    3 有的集合接口,提供一系列排列有序的元素,并且可以在序列中间快速的插入或者删除有关的元素。

    4 有的集合接口,提供映射关系,可以通过关键字(key)去快速查找到对应关系的唯一对象,可这个关键字可以使任意类型。

     

    集合与数组的对比:

    数组的长度或者说是容量是固定的,如果数组的长度不够用了,我们需要新建一个然后将原数组的元素复制进去,这样会很麻烦

    集合的长度(容量)可以在使用过程中动态扩展

    数组之能通过下标访问元素,类型固定,而有的集合可以通过任意类型查找所映射的具体对象

    Java中的集合体系分为(两类):

    Collection:

    下面有三个接口 List、 Queue、 Set

    List和Queue中存的元素是有序的,可以重复

    Set中存的元素无序且不可重复

    List下有一个常用的类ArraysList(数组序列)

    Queue下有一个常用的类LinkedList(链表)List接口同样可以使用

    Set下也有一个常用的类HashSet类

    Map:

    常用的有一个常用的实现类HashMap

     PS~:

    Collection类中存储的为一个一个独立的对象(一个一个的单身汉)

    Map类中会将<Key,Value>(Entry键值对)作为一个映射对象存储其中(一对一对的情侣)

     

    Collection接口:

    是List、Set、Queue接口的父接口

    定义了可用于操作List、Set、Queue的方法(增删改查)

    (具体方法可以参考JDK的API文档)

    因为文件较大无法上传,想要了解的朋友可以联系我,也可以直接上网自行百度

    List接口及其实现类——ArraysList

    List是元素有序并且可以重复的集合,被称为序列

    List可以精确的控制每一个元素的插入位置,或者删除某一个位置元素

    ArraysList--数组序列,是List的一个重要实现类

    ArraysList的底层是由数组实现的

    下面有一个具体的实例来应用一下List

    实现功能——模拟学生选课功能

    1 选择课程(往集合中添加课程)

    2 删除所选的某门课程(删除集合中的元素)

    3 查看所选的课程

    4 修改所选的课程

    学生选课——创建学生类和课程类

    import java.util.Set;  //这两个包不要忘记添加哦
    import java.util.HashSet;
    // 学生类
    public class Student {
    
        public String id;
        public String name;
        
        public Set courses;
        // 学生类的构造函数(含参构造器)
        public Student(String id, String name){
            this.id = id;
            this.name = name;
            // 初始化courses属性  Set是一个接口不能直接初始化
            // 所以这里用HashSet初始化 
            this.courses = new HashSet();
        }
    }
    
    // 课程类
    public class Course {
    
        public String id;
        public String name;
        
        // 课程类的构造函数(含参构造器)
        public Course(String id ,String name){
            this.id = id;
            this.name = name;
        }
    }

    学生选课——添加课程

    首先要将备选课程添加至List容器中(创建ListTest类)

      3 import java.sql.Array;
      4 import java.util.ArrayList;
      5 import java.util.Arrays;
      6 import java.util.Iterator;
      7 import java.util.List;
      8 
      9 public class ListTest {
     10         // 备选课程
     11     public List coursesToSelect;
     12     
     13         // ListTest类的构造方法
     14     public ListTest(){
     15         // List是一个接口不能直接初始化 使用List接口下的ArrayList类
     16         this.coursesToSelect = new ArrayList();
     17     }
     18     
     19     // 用于往coursesToSelect中添加备选课程
     20     public void testAdd(){
     21         // 创建一个课程对象,并通过调用add方法,添加到备选课程List中 
     22         Course cr1 = new Course("1","数据结构");
     23         coursesToSelect.add(cr1);
     24         /* 通过List的get方法取出元素,验证课程是否添加成功
     25          * 由于对象存入集合都变成里object类型,取出时需要类型转换
     26          * 由于这是添加的第一个课程信息所以下标为0
     27          */
     28         Course temp = (Course) coursesToSelect.get(0);
     29         System.out.println("添加了课程:" + temp.id + temp.name );
     30         
     31         
     32         
     33         /*
     34          * List中还重载了另一个add方法 该方法不仅可以添加新元素,
     35          * 而且可以指定添加的位置
     36          */
     37         Course cr2 = new Course("2","C语言");
     38         coursesToSelect.add(0,cr2); // 指定添加位置为0,原位置上的元素被挤下去
     39         Course temp2 = (Course) coursesToSelect.get(0);  // 类型强转
     40         System.out.println("添加了课程:" + temp2.id + temp2.name );
     41         
     42         
     43         /*
     44          * 在添加课程过程中,如果传递的位置参数大于现在的长度时(或者数组下标小于0)
     45          * 会报(IndexOutOfBoundsException)异常
     46          */    
     47 //        Course cr3 = new Course("3","概率论");
     48 //        coursesToSelect.add(4, cr3);
     49 //        Course temp3 = (Course) coursesToSelect.get(0);
     50 //        System.out.println("添加了课程" + temp3.id + temp3.name);
     51         
     52         
     53         /*
     54          * 除了add方法 还有另外两种方法可以实现往List中添加课程
     55          * addAll方法 首先将course数组通过Arrays的asList方法转变为List
     56          * 1 直接利用addAll添加课程   2 通过传递一个位置参数将课程添加至指定位置
     57          */
     58         Course[] course = {new Course("4","离散数学"), new Course("5","汇编语言")};
     59         coursesToSelect.addAll(Arrays.asList(course));
     60         Course temp4 = (Course) coursesToSelect.get(2);
     61         Course temp5 = (Course) coursesToSelect.get(3);
     62         System.out.println("添加了两门课程:" + temp4.id + temp4.name + 
     63                 temp5.id + temp5.name);
     64         
     65         Course[] course2 = {new Course("6","高等数学"), new Course("6","大学英语")}; 
     66         coursesToSelect.addAll(2,Arrays.asList(course2));
     67         Course temp6 = (Course) coursesToSelect.get(2);
     68         Course temp7 = (Course) coursesToSelect.get(3);
     69         System.out.println("添加了两门课程:" + temp6.id + temp6.name + 
     70                 temp7.id + temp7.name);
     71         
     72             
     73         // List中的元素可以重复 以下是代码演示
     74 //        coursesToSelect.add(cr1);
     75 //        Course temp0 = (Course) coursesToSelect.get(6);
     76 //        System.out.println("添加了课程:" + temp0.id + temp0.name );
     77         
     78     }
     79     
     80     
     81     // 取得List中的元素的方法 
     82     public void testGet(){
     83         System.out.println();
     84         int size = coursesToSelect.size(); // 取得List中的元素个数
     85         System.out.println("有如下课程待选:");
     86         for (int i = 0; i < size; i ++){
     87             Course cr = (Course) coursesToSelect.get(i);
     88             System.out.println("课程:"+cr.id + cr.name);
     89         }
     90     }
     91     
     92     
     93     /*
     94      * 通过迭代器来遍历List
     95      * 迭代器只用来遍历集合中元素,本身不具备存储功能
     96      * 还有另一种写法(简便版) ForEach
     97      */
     98     public void testIterator(){
     99         System.out.println();
    100         // 通过集合的iterator方法,取得迭代器的实例
    101         Iterator it = coursesToSelect.iterator();
    102         System.out.println("有如下课程待选(通过迭代器访问):");
    103         while (it.hasNext()){
    104             Course cr = (Course) it.next();
    105             System.out.println("课程:"+cr.id + cr.name);
    106         }
    107     }
    108     // 通过for each 方法访问集合元素
    109     public void testForEach(){
    110         System.out.println();
    111         System.out.println("有如下课程可选(通过for each访问):");
    112         for (Object obj : coursesToSelect){
    113             Course cr = (Course)obj;
    114             System.out.println("课程:" + cr.id + cr.name);
    115         }
    116     }
    117     
    118     /*
    119      * 修改List中的元素
    120      * 利用List中的Set方法修改元素值
    121      * set中有两个参数 位置参数 更改的值
    122      */
    123     public void testModify(){
    124         coursesToSelect.set(4, new Course("7","毛概"));
    125     }
    126     
    127     
    128     // 删除List中的元素 有两种方法法
    129     public void testRemove (){
    130         System.out.println();
    131         Course cr = (Course) coursesToSelect.get(4);
    132         System.out.println("我是课程:"+cr.id + cr.name+"我即将被删除");
    133         coursesToSelect.remove(cr);
    134         // 也可以直接删除指定位置上的元素  效果一样
    135         // coursesToSelect.remove(4);  
    136         System.out.println("成功删除课程!");
    137         testForEach();
    138         
    139 //        System.out.println("即将删除4位置和5位置上的元素!");
    140 //        Course[] courses = {(Course) coursesToSelect.get(3),(Course) coursesToSelect.get(4)};
    141 //        coursesToSelect.removeAll(Arrays.asList(courses));
    142 //        System.out.println("成功删除课程!");
    143 //        testForEach();
    144     }
    145     
    146     
    147     /*
    148      * 前面我们所添加的都是一些正常的课程信息(课程id,课程name)
    149      * 但是当我们添加了一些“不正常的信息”时 会怎么样嘞?
    150      * 下面我们来试验一下:
    151      *            往List中添加一些奇怪的东西
    152      *  运行之后你会发现 程序并没有add成功
    153      *  并且抛出了一个 ClassCastException异常(String类型不能被强转为course类型)
    154      *  
    155      *  
    156      *  有木有办法控制我们往某一个集合或者List中添加元素的类型嘞?
    157      *         YES 这里我们可以利用 “泛型” 关于泛型的概念在下面会有介绍
    158      */
    159     
    160 //    public void testType(){
    161 //        System.out.println("能否往List中添加一些奇怪的东西呢?");
    162 //        coursesToSelect.add("我不是课程 我只是一个字符串!");
    163 //    }
    164     
    165     
    166     public static void main (String[] args){
    167         // 创建ListTest 对象的实例
    168         ListTest lt = new ListTest();
    169         lt.testAdd();
    170         lt.testGet();
    171         lt.testIterator();
    172         lt.testForEach();
    173         lt.testModify();
    174         lt.testForEach();
    175         lt.testRemove();
    176         //lt.testType();
    177         lt.testForEach();
    178     }
    179     
    180 }
    添加了课程:1数据结构
    添加了课程:2C语言
    添加了两门课程:4离散数学5汇编语言
    添加了两门课程:6高等数学6大学英语
    
    有如下课程待选:
    课程:2C语言
    课程:1数据结构
    课程:6高等数学
    课程:6大学英语
    课程:4离散数学
    课程:5汇编语言
    
    有如下课程待选(通过迭代器访问):
    课程:2C语言
    课程:1数据结构
    课程:6高等数学
    课程:6大学英语
    课程:4离散数学
    课程:5汇编语言
    
    有如下课程可选(通过for each访问):
    课程:2C语言
    课程:1数据结构
    课程:6高等数学
    课程:6大学英语
    课程:4离散数学
    课程:5汇编语言
    
    有如下课程可选(通过for each访问):
    课程:2C语言
    课程:1数据结构
    课程:6高等数学
    课程:6大学英语
    课程:7毛概
    课程:5汇编语言
    
    我是课程:7毛概我即将被删除
    成功删除课程!
    
    有如下课程可选(通过for each访问):
    课程:2C语言
    课程:1数据结构
    课程:6高等数学
    课程:6大学英语
    课程:5汇编语言
    
    有如下课程可选(通过for each访问):
    课程:2C语言
    课程:1数据结构
    课程:6高等数学
    课程:6大学英语
    课程:5汇编语言
    Output

    泛型:

    用于控制往某个集合或者List中添加元素的类型

    集合中的元素,可以是任意类型的对象(对象的引用)

    如果把某一个对象放入到集合,则会忽略他的类型而把它当做Object处理

    泛型则是规定了某个集合只可以存放特定类型的对象,并且会在编译过程中进行类型检查。可以直接按指定类型获取集合元素

    注意:

    泛型集合中的限定类型不能使用基本数据类型。

    可以通过使用 包装类 限定允许存入的基本数据类型。

     1    /*
     2     * ChildCourse 继承Course类型 而Course中我们定义了一个含参构造器
     3     * 所以编译器就不会再自动添加一个隐式的无参构造器
     4     * 但是在Course的子类(该类)中必须要调用父类的隐式构造器
     5     * 所以这里会提示错误
     6     *             这是我们只需要再course类中手动添加一个无参构造器即可
     7     */
     8 public class ChildCourse extends Course {
     9     
    10     /*
    11      * ChildCourse无需再添加任何属性
    12      * 所有的属性均继承Course类型的属性即可
    13      */
    14 }
    15 
    16 import java.util.ArrayList;
    17 import java.util.List;
    18 
    19 public class TestGeneric {
    20 
    21     // 带有泛型——Course,的List类型属性
    22     public List<Course> courses;
    23     
    24     public TestGeneric(){ // 因为指定了泛型 所以这里要加上<Course>
    25         this.courses = new ArrayList<Course>(); // 后面的圆括号表示调用了构造方法
    26     }
    27     
    28     // 测试添加
    29     public void testAdd(){
    30         Course cr1 = new Course("1","大学语文");
    31         courses.add(cr1);
    32         /*
    33          *  当添加的信息不正确时 编译器会直接报错
    34          *  泛型集合中,不能添加泛型规定的类型及其子类型以外的对象,否则会报错
    35          */
    36         //courses.add("能否添加一些奇怪的东西?");
    37         Course cr2 = new Course("2","Java基础教程");
    38         courses.add(cr2);
    39     }
    40     
    41     // 测试循环遍历
    42     public void testForEach(){
    43         // 这里的course在编译的时候已经规定了泛型,所以这里不用再把当做Object类型转换
    44         for (Course cr:courses){
    45             System.out.println(cr.id + cr.name);
    46             
    47         }
    48     }
    49     
    50     // 测试泛型集合可以添加泛型的子类型的塑像实例
    51     public void testChild (){
    52         ChildCourse ccr = new ChildCourse();
    53         ccr.id = "3";
    54         ccr.name = "我是子类型的课程对象实例~~";
    55         courses.add(ccr);
    56     }
    57     
    58     /*
    59      * 注意:
    60      * 泛型集合中的限定类型不能使用基本数据类型。
    61      * 可以通过使用 包装类 限定允许存入的基本数据类型。
    62      */
    63     public void testBasicType(){
    64         // 这里如果写成int的话编译器会报错,所以要用Integer
    65         List<Integer> list = new ArrayList<Integer>();
    66         list.add(1);  // 这里的1(基本类型) 被强制转换成了int的包装类Integer,然后被加入到list中
    67         System.out.println("基本类型必须使用包装类作为泛型" + list.get(0));
    68     }
    69     
    70     
    71     public static void main(String[] args) {
    72         
    73         TestGeneric tg = new TestGeneric();
    74         tg.testAdd();
    75         tg.testForEach();
    76         
    77         tg.testChild();
    78         tg.testForEach();
    79         
    80         tg.testBasicType();
    81     }
    82 
    83 }
    1大学语文
    2Java基础教程
    1大学语文
    2Java基础教程
    3我是子类型的课程对象实例~~
    基本类型必须使用包装类作为泛型1
    Output

    学生选课——通过set集合管理课程

    Set接口及其实现类——HashSet

    Set是元素无序并且不可以不可以重复的集合,被称为集

    HashSet——哈希集,是set的一个重要实现类

    Set中没有提供像list中的set()方法(修改指定位置上的元素):list——有序    set——无序

     

    下面通过实例来形象的说明一下吧

    案例功能说明:

      1 提供备选课程

      2 创建学生对象,并给该学生添加三门课程(添加到学生的courses——set类型的属性中)

        显示备选课程

        循环三次,每次输入课程ID

        往学生的courses属性中添加与输入的ID匹配的课程

        输出学生选择的课程

      1 import java.util.ArrayList;
      2 import java.util.Arrays;
      3 import java.util.List;
      4 import java.util.Scanner;
      5 public class SetTest {
      6 
      7     /*
      8      * 在前面的student类中 我们定义了一个set类型的属性
      9      * 在这里 我们需要将上面student类中的set属性加一个泛型
     10      */
     11     
     12     public List<Course> coursesToSelect;
     13     
     14     public SetTest(){
     15         coursesToSelect = new ArrayList<Course>();
     16         
     17         
     18     }
     19     
     20     
     21     /*
     22      * 这里我们可以小小的偷个懒,将刚才写过的testAdd直接复制过来
     23      * 同时将所有多余的打印输出注释掉    
     24      */
     25     // 用于往coursesToSelect中添加备选课程
     26         public void testAdd(){
     27             // 创建一个课程对象,并通过调用add方法,添加到备选课程List中 
     28             Course cr1 = new Course("1","数据结构");
     29             coursesToSelect.add(cr1);
     30             /* 通过List的get方法取出元素,验证课程是否添加成功
     31              * 由于对象存入集合都变成里object类型,取出时需要类型转换
     32              * 由于这是添加的第一个课程信息所以下标为0
     33              */
     34             Course temp = (Course) coursesToSelect.get(0);
     35             //System.out.println("添加了课程:" + temp.id + temp.name );
     36             
     37             
     38             
     39             /*
     40              * List中还重载了另一个add方法 该方法不仅可以添加新元素,
     41              * 而且可以指定添加的位置
     42              */
     43             Course cr2 = new Course("2","C语言");
     44             coursesToSelect.add(0,cr2); // 指定添加位置为0,原位置上的元素被挤下去
     45             Course temp2 = (Course) coursesToSelect.get(0);  // 类型强转
     46             //System.out.println("添加了课程:" + temp2.id + temp2.name );
     47             
     48             
     49             /*
     50              * 在添加课程过程中,如果传递的位置参数大于现在的长度时(或者数组下标小于0)
     51              * 会报(IndexOutOfBoundsException)异常
     52              */    
     53 //            Course cr3 = new Course("3","概率论");
     54 //            coursesToSelect.add(4, cr3);
     55 //            Course temp3 = (Course) coursesToSelect.get(0);
     56 //            System.out.println("添加了课程" + temp3.id + temp3.name);
     57             
     58             
     59             /*
     60              * 除了add方法 还有另外两种方法可以实现往List中添加课程
     61              * addAll方法 首先将course数组通过Arrays的asList方法转变为List
     62              * 1 直接利用addAll添加课程   2 通过传递一个位置参数将课程添加至指定位置
     63              */
     64             Course[] course = {new Course("4","离散数学"), new Course("5","汇编语言")};
     65             coursesToSelect.addAll(Arrays.asList(course));
     66             Course temp4 = (Course) coursesToSelect.get(2);
     67             Course temp5 = (Course) coursesToSelect.get(3);
     68             //System.out.println("添加了两门课程:" + temp4.id + temp4.name + 
     69             //        temp5.id + temp5.name);
     70             
     71             Course[] course2 = {new Course("6","高等数学"), new Course("6","大学英语")}; 
     72             coursesToSelect.addAll(2,Arrays.asList(course2));
     73             Course temp6 = (Course) coursesToSelect.get(2);
     74             Course temp7 = (Course) coursesToSelect.get(3);
     75             //System.out.println("添加了两门课程:" + temp6.id + temp6.name + 
     76             //        temp7.id + temp7.name);
     77             
     78                 
     79             // List中的元素可以重复 以下是代码演示
     80 //            coursesToSelect.add(cr1);
     81 //            Course temp0 = (Course) coursesToSelect.get(6);
     82 //            System.out.println("添加了课程:" + temp0.id + temp0.name );
     83             
     84         }
     85         
     86 
     87         // 通过for each 方法访问集合元素
     88         public void testForEach(){
     89             System.out.println();
     90             System.out.println("有如下课程可选(通过for each访问):");
     91             for (Object obj : coursesToSelect){
     92                 Course cr = (Course)obj;
     93                 System.out.println("课程:" + cr.id + cr.name);
     94             }
     95         }
     96         
     97     
     98     
     99     public static void main(String[] args) {
    100         
    101         SetTest st = new SetTest();
    102         st.testAdd();
    103         st.testForEach();
    104         
    105         // 创建一个学生对象
    106         Student student = new Student("1","小明");
    107         System.out.println("欢迎学生:"+ student.name + "选课");
    108         // 创建一个Scanner ,用来接收从键盘输入的课程ID
    109         Scanner console = new Scanner(System.in);
    110         
    111         /*
    112          * 输入三个ID 选三门课
    113          * 将每一个ID 跟coursesToSelect中的每一个课程对象比较
    114          * 如果ID相等的情况下,就将该课程对象添加到小明的选课信息中
    115          */
    116         for (int i = 0; i < 3; i ++){
    117             System.out.println("请输入课程ID:");
    118             String courseId = console.next();
    119             for (Course cr:st.coursesToSelect){
    120                 if (cr.id.equals(courseId)){
    121                     student.courses.add(cr);
    122                     student.courses.add(cr);  //验证set中元素不可重复
    123                     // set 中添加某个对象,无论添加多少次最终只会保留一个该对象(的引用)
    124                 }
    125             }
    126         }
    127         st.testForEachForSet(student);
    128     }
    129 
    130     public void testForEachForSet(Student student){
    131         
    132         //验证set中元素不可重复
    133         System.out.println("共选择了:" + student.courses.size() + "门课程");
    134         
    135         /*
    136          *  打印输出,学生所选的课程!
    137          *  这里需要说明一点 循环遍历set中的元素 只能用佛reach方法或者
    138          *  iterator方法,而不能像list那样调用get()方法
    139          *  这是因为set本身是无序的,所以不可能去查询指定位置上的元素
    140          *  只能通过循环迭代出来  由于它是无序的所以每一次他的结果都是不太一样的
    141          */
    142         
    143         for (Course cr:student.courses){
    144             System.out.println("选择了课程:" + cr.id + cr.name);
    145             
    146         }
    147     }
    148 }

    PS~ 如有手误  欢迎指出

  • 相关阅读:
    [iOS]delegate和protocol
    Objective-c中@interface、@implementation、@protocal
    iOS应用的真机调试
    2016最新Java笔试题集锦
    Java面试题相关内容
    JSP面试题及答案
    JAVA面试题相关基础知识
    mysql workbench建表时PK,NN,UQ,BIN,UN,ZF,AI
    Java中equals和==的区别
    java的Arrays类的应用
  • 原文地址:https://www.cnblogs.com/yoke/p/6979621.html
Copyright © 2011-2022 走看看