15. 集合类(Collection、List)

来源:互联网 发布:萧敬腾唱功知乎 编辑:程序博客网 时间:2024/06/06 03:44

1:对象数组(掌握)

       (1)数组既可以存储基本数据类型,也可以存储引用类型。它存储引用类型的时候的数组就叫对象数组。

       (2)案例:

              用数组存储5个学生对象,并遍历数组。

public class Student {       //成员变量       privateString name;       privateint age;       //构造方法       publicStudent() {              super();       }       publicStudent(String name, int age) {              super();              this.name= name;              this.age= age;       }       //成员方法       //getXxx()/setXxx()       publicString getName() {              returnname;       }       publicvoid setName(String name) {              this.name= name;       }       publicint getAge() {              returnage;       }       publicvoid setAge(int age) {              this.age= age;       }       @Override       publicString toString() {              return"Student [name=" + name + ", age=" + age + "]";       }}

----------------------------------------------------------------------------------------------------------------------------------------

* 我有5个学生,请把这个5个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息。

 *           学生:Student

 *           成员变量:name,age

 *           构造方法:无参,带参

 *           成员方法:getXxx()/setXxx()

 *           存储学生的数组?自己想想应该是什么样子的?

 * 分析:

 *          A:创建学生类。

 *          B:创建学生数组(对象数组)。

 *          C:创建5个学生对象,并赋值。

 *          D:把C步骤的元素,放到数组中。

 *          E:遍历学生数组。

 */

publicclass ObjectArrayDemo {   public static void main(String[] args) {          // 创建学生数组(对象数组)。          Student[] students =new Student[5];          // for (int x = 0; x <students.length; x++) {          // System.out.println(students[x]);          // }          // System.out.println("---------------------");          // 创建5个学生对象,并赋值。          Student s1 = newStudent("林青霞", 27);          Student s2 = newStudent("风清扬", 30);          Student s3 = newStudent("刘意", 30);          Student s4 = newStudent("赵雅芝", 60);          Student s5 = newStudent("王力宏", 35);          // 把C步骤的元素,放到数组中。          students[0] = s1;          students[1] = s2;          students[2] = s3;          students[3] = s4;          students[4] = s5;          // 看到很相似,就想循环改          // for (int x = 0; x <students.length; x++) {          // students[x] = s + "" + (x+ 1);          // }          // 这个是有问题的          // 遍历          for (int x = 0; x< students.length; x++) {                 //System.out.println(students[x]);                        Students = students[x];                 System.out.println(s.getName()+"---"+s.getAge());          }    }}

2:集合(Collection)(掌握)

       (1)集合的由来?

              我们学习的是Java -- 面向对象 -- 操作很多对象 -- 存储 -- 容器(数组和StringBuffer) -- 数组

              而数组的长度固定,所以不适合做变化的需求,Java就提供了集合供我们使用。

      (2)集合和数组的区别?

              A:长度区别

                     数组固定

                     集合可变

              B:内容区别

                     数组可以是基本类型,也可以是引用类型

                     集合只能是引用类型

              C:元素内容

                     数组只能存储同一种类型

                     集合可以存储不同类型(其实集合一般存储的也是同一种类型)

      (3)Collection的功能概述

           1:添加功能

             booleanadd(Object obj):              添加一个元素

             booleanaddAll(Collection c):       添加一个集合的元素

2:删除功能

             voidclear():                                移除所有元素

             booleanremove(Object o):           移除一个元素

             booleanremoveAll(Collection c):  移除一个集合的元素(是一个还是所有)

只要有一个元素被移除了,就返回true

          3:判断功能

              boolean contains(Objecto):        判断集合中是否包含指定的元素

             booleancontainsAll(Collection c):判断集合中是否包含指定的集合元素(是一个还是所有)

只有包含所有的元素,才叫包含

             booleanisEmpty():                   判断集合是否为空

         4:获取功能

             Iterator<E>iterator()(重点)

5:长度功能

             intsize():元素的个数

public class CollectionDemo {   publicstatic void main(String[] args) {          //测试不带All的方法          //创建集合对象          //Collection c = new Collection(); //错误,因为接口不能实例化          Collection c = new ArrayList();          //boolean add(Object obj):添加一个元素          //System.out.println("add:"+c.add("hello"));          c.add("hello");          c.add("world");          c.add("java");          // void clear():移除所有元素          // c.clear();          // boolean remove(Object o):移除一个元素          // System.out.println("remove:" +c.remove("hello"));          // System.out.println("remove:" +c.remove("javaee"));          // boolean contains(Object o):判断集合中是否包含指定的元素          //System.out.println("contains:"+c.contains("hello"));          //System.out.println("contains:"+c.contains("android"));          // boolean isEmpty():判断集合是否为空          // System.out.println("isEmpty:"+c.isEmpty());          //int size():元素的个数          System.out.println("size:"+c.size());          System.out.println("c:" + c);   }}

         面试题:数组有没有length()方法呢?字符串有没有length()方法呢?集合有没有length()方法呢?

没有,有,没有

         6:交集功能

              boolean retainAll(Collectionc):两个集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢?

假设有两个集合AB

              AB做交集,最终的结果保存在A中(谁调用这个方法,元素就被谁保存),B不变。

              返回值表示的是A是否发生过改变

public class CollectionDemo2 {   publicstatic void main(String[] args) {          // 创建集合1          Collection c1 = new ArrayList();          c1.add("abc1");          c1.add("abc2");          c1.add("abc3");          c1.add("abc4");          // 创建集合2          Collection c2 = new ArrayList();//        c2.add("abc1");//        c2.add("abc2");//        c2.add("abc3");//        c2.add("abc4");          c2.add("abc5");          c2.add("abc6");          c2.add("abc7");          //boolean addAll(Collection c):添加一个集合的元素          //System.out.println("addAll:" + c1.addAll(c2));          //booleanremoveAll(Collection c):移除一个集合的元素(是一个还是所有)          //只要有一个元素被移除了,就返回true。          //System.out.println("removeAll:"+c1.removeAll(c2));//booleancontainsAll(Collection c):判断集合中是否包含指定的集合元素(是一个还是所有)          //只有包含所有的元素,才叫包含          //System.out.println("containsAll:"+c1.containsAll(c2));//booleanretainAll(Collection c):两个集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢?          //假设有两个集合A,B。          //A对B做交集,最终的结果保存在A中,B不变。          //返回值表示的是A是否发生过改变。          System.out.println("retainAll:"+c1.retainAll(c2));          System.out.println("c1:"+ c1);          System.out.println("c2:" +c2);   }}

         7:把集合转换为数组

             Object[]toArray():把集合转成数组,可以实现集合的遍历

public class CollectionDemo3 {       publicstatic void main(String[] args) {              //创建集合对象              Collectionc = new ArrayList();              //添加元素              c.add("hello");// Object obj = "hello"; 向上转型              c.add("world");              c.add("java");              //遍历              //Object[] toArray():把集合转成数组,可以实现集合的遍历              Object[]objs = c.toArray();              for(int x = 0; x < objs.length; x++) {                     //System.out.println(objs[x]);              //我知道元素是字符串,我在获取到元素的的同时,还想知道元素的长度。                     //System.out.println(objs[x] + "---" + objs[x].length());                     //上面的实现不了,原因是Object中没有length()方法                     //我们要想使用字符串的方法,就必须把元素还原成字符串                     //向下转型                     Strings = (String) objs[x];                     System.out.println(s+ "---" + s.length());              }       }}

------------------------------------------------------------------------------------------------------------------------------------------

      (4)Collection集合的遍历

              A:把集合转数组(了解)

              B:迭代器(集合专用方式)

Iteratoriterator():                        迭代器,集合的专用遍历方式

                     Object next():                             获取元素,并移动到下一个位置。

                    NoSuchElementException:        没有这样的元素,因为你已经找到最后了。

                    booleanhasNext():                      如果仍有元素可以迭代,则返回 true。

------------------------------------------------------------------------------------------------------------------------------------------

    publicstatic void main(String[] args) {           //创建集合对象           Collectionc = new ArrayList();           //创建并添加元素           //String s = "hello";           //c.add(s);           c.add("hello");           c.add("world");           c.add("java");           //Iterator iterator():迭代器,集合的专用遍历方式           Iteratorit = c.iterator(); // 实际返回的肯定是子类对象,这里是多态            //Object obj = it.next();           //System.out.println(obj);           //System.out.println(it.next());           //System.out.println(it.next());           //System.out.println(it.next());           //System.out.println(it.next());           //最后一个不应该写,所以,我们应该在每次获取前,如果有一个判断就好了           //判断是否有下一个元素,有就获取,没有就不搭理它           //if (it.hasNext()) {           //System.out.println(it.next());           //}           //if (it.hasNext()) {           //System.out.println(it.next());           //}           //if (it.hasNext()) {           //System.out.println(it.next());           //}           //if (it.hasNext()) {           //System.out.println(it.next());           //}           //if (it.hasNext()) {           //System.out.println(it.next());           //}           //最终版代码           while(it.hasNext()) {                  //System.out.println(it.next());                  Strings = (String) it.next();                  System.out.println(s);           }    }}

       (5)迭代器

              A:是集合的获取元素的方式。

              B:是依赖于集合而存在的。

              C:迭代器的原理和源码。

                     a:为什么定义为了一个接口而不是实现类?

                     b:看了看迭代器的内部类实现。

       (6)Collection集合的案例(遍历方式迭代器)

              集合的操作步骤:

                     A:创建集合对象

                     B:创建元素对象

                     C:把元素添加到集合

                     D:遍历集合

              A:存储字符串并遍历

                     importjava.util.Collection;                     import java.util.ArrayList;                     import java.util.Iterator;                     public class CollectionDemo{                            public static voidmain(String[] args) {                                   //创建集合对象                                   Collection c= new ArrayList();                                   //创建并添加元素                                   c.add("hello");                                   c.add("world");                                   c.add("java");                                   //遍历集合                                   Iterator it =c.iterator();                                   while(it.hasNext()){                                          Strings =(String) it.next();                                          System.out.println(s);                                   }                            }                     }

              B:存储自定义对象并遍历

                     public class Student {                            private String name;                            private int age;                            public Student(){}                            publicStudent(String name,int age) {                                   this.name =name;                                   this.age =age;                            }                            //getXxx()/setXxx()                     }                     importjava.util.Collection;                     import java.util.ArrayList;                     import java.util.Iterator;                     public class StudentDemo {                            public static voidmain(String[] args) {                                   //创建集合对象                                   Collection c= new ArrayList();                                   //创建学生对象                                   Student s1 =new Student("林青霞",27);                                   Student s2 =new Student("风清扬",30);                                   Student s3 =new Student("刘意",30);                                   Student s4 =new Student("武鑫",25);                                   Student s5 =new Student("刘晓曲",16);                                  //添加元素                                   c.add(s1);                                   c.add(s2);                                   c.add(s3);                                   c.add(s4);                                   c.add(s5);                                   //遍历集合                                   Iterator it =c.iterator();                                   while(it.hasNext()){                                          Students = (Student)it.next();                                          System.out.println(s.getName()+"---"+s.getAge());//NoSuchElementException 不要多次使用it.next()方法,因为每次使用都是访问一个对象。                     //System.out.println(((Student) it.next()).getName() + "---"                     //+ ((Student) it.next()).getAge());// for循环改写(速度快,效率高)              //for(Iterator it = c.iterator();it.hasNext();){              //Student s = (Student) it.next();              //System.out.println(s.getName() + "---" + s.getAge());              //}                                   }                            }                     }

3:集合(List)(掌握)

       (1)List是Collection的子接口

              特点:有序(存储顺序和取出顺序一致),可重复。

      (2)List的特有功能:

              A:添加功能                  void add(intindex,Object element):      在指定位置添加元素

             B:获取功能                  Objectget(int index):                          获取指定位置的元素

             C:列表迭代器              ListIteratorlistIterator():                   List集合特有的迭代器

             D:删除功能                  Objectremove(int index):                 根据索引删除元素,返回被删除的元素

E:修改功能           Object set(intindex,Object element):    根据索引修改元素,返回被修饰的元素

public class ListDemo {       publicstatic void main(String[] args) {              //创建集合对象              Listlist = new ArrayList();              //添加元素              list.add("hello");              list.add("world");              list.add("java");              //void add(int index,Object element):在指定位置添加元素              //list.add(1, "android");//没有问题              //IndexOutOfBoundsException              //list.add(11, "javaee");//有问题              //list.add(3, "javaee"); //没有问题              //list.add(4, "javaee"); //有问题              //Object get(int index):获取指定位置的元素              //System.out.println("get:" + list.get(1));              //IndexOutOfBoundsException              //System.out.println("get:" + list.get(11));              //Object remove(int index):根据索引删除元素,返回被删除的元素              //System.out.println("remove:" + list.remove(1));              //IndexOutOfBoundsException              //System.out.println("remove:" + list.remove(11));              //Object set(int index,Object element):根据索引修改元素,返回被修饰的元素              System.out.println("set:"+ list.set(1, "javaee"));              System.out.println("list:"+ list);       }}

      (3)List集合的特有遍历功能

              A:由size()和get()结合(普通For

              B:代码演示

public class ListDemo2 {   publicstatic void main(String[] args) {          //创建集合对象          Listlist = new ArrayList();    //添加元素          list.add("hello");          list.add("world");          list.add("java");          //Object get(int index):获取指定位置的元素          //System.out.println(list.get(0));          //System.out.println(list.get(1));          //System.out.println(list.get(2));          // IndexOutOfBoundsException          //System.out.println(list.get(3));          //用循环改进          //for (int x = 0; x < 3; x++) {          //System.out.println(list.get(x));          //}          //如果元素过多,数起来就比较麻烦,所以我们使用集合的一个长度功能:size()          //最终的遍历方式就是:size()和get()          for(int x = 0; x < list.size(); x++) {                 //System.out.println(list.get(x));                 Strings = (String) list.get(x);                 System.out.println(s);          }   }} 

(4) List集合列表迭代器的特有功能;(逆向遍历了解)

ListIteratorlistIterator():List集合特有的迭代器

该迭代器继承了Iterator迭代器,所以,就可以直接使用hasNext()和next()方法。

可以逆向遍历,但是要先正向遍历,所以无意义,基本不使用。

Object previous():         获取上一个元素

boolean hasPrevious():   判断是否有元素

注意:ListIterator可以实现逆向遍历,但是必须先正向遍历,才能逆向遍历,所以一般无意义,不使用。

public class ListIteratorDemo {       publicstatic void main(String[] args) {              //创建List集合对象              Listlist = new ArrayList();              list.add("hello");              list.add("world");              list.add("java");              //ListIterator listIterator()              ListIteratorlit = list.listIterator(); // 子类对象              //while (lit.hasNext()) {              //String s = (String) lit.next();              //System.out.println(s);              //}              //System.out.println("-----------------");              //System.out.println(lit.previous());              //System.out.println(lit.previous());              //System.out.println(lit.previous());              //NoSuchElementException              //System.out.println(lit.previous());              while(lit.hasPrevious()) {                     Strings = (String) lit.previous();                     System.out.println(s);              }              System.out.println("-----------------");               //迭代器              Iteratorit = list.iterator();              while(it.hasNext()) {                     Strings = (String) it.next();                     System.out.println(s);              }              System.out.println("-----------------");        }}

       (5)并发修改异常

              A:出现的现象

                     迭代器遍历集合,集合修改集合元素

              B:原因

迭代器是依赖于集合而存在的,在判断成功后,集合的中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常ConcurrentModificationException

其实这个问题描述的是:迭代器遍历元素的时候,通过集合是不能修改元素的。

              C:解决方案

                     a:迭代器遍历,迭代器修改(ListIterator)

                            元素添加在刚才迭代的位置

                     b:集合遍历,集合修改(size()和get())

                            元素添加在集合的末尾

public class ListIteratorDemo2 {    publicstatic void main(String[] args) {           //创建List集合对象           Listlist = new ArrayList();           //添加元素           list.add("hello");           list.add("world");           list.add("java");           //迭代器遍历(错误)           //Iterator it = list.iterator();           //while (it.hasNext()) {           //String s = (String) it.next();           //if ("world".equals(s)) {           //list.add("javaee");           //}           //}           // 方式1:迭代器迭代元素,迭代器修改元素           //而Iterator迭代器却没有添加功能,所以我们使用其子接口ListIterator           //ListIterator lit = list.listIterator();           //while (lit.hasNext()) {           //String s = (String) lit.next();           //if ("world".equals(s)) {           //lit.add("javaee");           //}           //}           // 方式2:集合遍历元素,集合修改元素(普通for)           for(int x = 0; x < list.size(); x++) {                  Strings = (String) list.get(x);                  if("world".equals(s)) {                         list.add("javaee");                  }           }           System.out.println("list:"+ list);    }}

       (6)常见数据结构

              A:栈      先进后出

              B:队列  先进先出

              C:数组  查询快,增删慢

              D:链表  查询慢,增删快

      (7)List的子类特点(面试题)

              ArrayList

                     底层数据结构是数组,查询快,增删慢。

                     线程不安全,效率高。

              Vector

                     底层数据结构是数组,查询快,增删慢。

                     线程安全,效率低。

              LinkedList

                     底层数据结构是链表,查询慢,增删快。

                     线程不安全,效率高。

              到底使用谁呢?看需求?

              分析:

                     要安全吗?

                            要:Vector(即使要,也不使用这个,后面再说)

                            不要:ArrayList或者LinkedList

                                   查询多;ArrayList

                                   增删多:LinkedList

              什么都不知道,就用ArrayList

4.练习

       (8)List集合的案例(遍历方式迭代器和普通for)

              A:存储字符串并遍历

public class ListDemo2 {       publicstatic void main(String[] args) {              //创建集合对象              Listlist = new ArrayList();              //存储元素              list.add("hello");              list.add("world");              list.add("java");              list.add("javaee");              list.add("android");              list.add("javaee");              list.add("android");              //遍历集合              Iteratorit = list.iterator();              while(it.hasNext()) {                     Strings = (String) it.next();                     System.out.println(s);              }       }}

              B:存储自定义对象并遍历

public class Student {       //成员变量       privateString name;       privateint age;       //构造方法       publicStudent() {              super();       }       publicStudent(String name, int age) {              super();              this.name= name;              this.age= age;       }       //成员方法       //getXxx()/setXxx()       publicString getName() {              returnname;       }       publicvoid setName(String name) {              this.name= name;       }       publicint getAge() {              returnage;       }       publicvoid setAge(int age) {              this.age= age;       }}


public class ListDemo {       publicstatic void main(String[] args) {              //创建集合对象              Listlist = new ArrayList();              //创建学生对象              Students1 = new Student("白骨精",30);              Students2 = new Student("蜘蛛精",40);              Students3 = new Student("观音姐姐",22);              //把学生对象添加到集合对象中              list.add(s1);              list.add(s2);              list.add(s3);              //遍历              Iteratorit = list.iterator();              while(it.hasNext()) {                     Students = (Student) it.next();                     System.out.println(s.getName()+ "---" + s.getAge());  }     }}