集合 (From Day 1)

正式讲课之前,我们先来搞明白三个小问题:

  1. 为什么需要集合类?

很多情况下,我们需要对一组对象进行操作。而且很可能事先并不知道到底有多少个对象。为了解决这个问题呢,Java 就提供了集合类供我们使用。

  1. 集合类的特点
        a. 只能存储引用数据类型
        b. 可以自动地调整自己的大小
  1. 数组和集合类都是容器,它们有何不同?
        a. 数组可以存储基本数据类型的数据,集合不可以。
        b. 数组的长度是固定的,集合可以自动调整自己的大小。
        c. 数组的效率高,相对来说集合效率比较低。
        d. 数组没有API,集合有丰富的API。(丰富的API挺重要)

1. Collection接口

1)概述
        a. Collection是层次结构中的根接口。
        b. Collection表示一组对象,这些对象也称为 collection 的元素。
        c. 一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。
2)API
API:
    增:
         boolean add(E e)               (给collection集合添加指定的元素,可添加重复的元素)
         
         boolean addAll(Collection c)   (将指定 collection 中的所有元素都添加到此 collection 中,如果原集合发生了修改,返回true, 否则返回false. )

例:
        boolean add(E e):

        Collection c = new ArrayList();
        c.add("hello");
        c.add("world");
        c.add("java");

        Collection c1 = new ArrayList();
        c1.add("beijing");
        c1.add("shanghai");
        c1.add("shenzhen");

        System.out.println(c.addAll(c1)); // true
        System.out.println(c); // [hello, world, java, beijing, shanghai, wuhan]
        System.out.println(c1); // [beijing, shanghai, wuhan]

        Collection c2 = new ArrayList();
        System.out.println(c.addAll(c2)); // false
        System.out.println(c);//[hello, world, java]
        System.out.println(c2);//[]  

        
API::
         void clear()                   (移除此 collection 中的所有元素)
         
         boolean remove(Object o)       (从此 collection 中移除指定元素的单个实例,如果存在的话,返回true,不存在,则返回false)
         
         boolean removeAll(Collection c)(移除此 collection 中那些也包含在指定 collection 中的所有元素,如果原集合发生了修改,返回true, 否则返回false)
         
         boolean retainAll(Collection c)(仅保留此 collection 中那些也包含在指定 collection 的元素,如果原集合发生了修改,返回true, 否则返回false.)
         
例:
        boolean removeAll(Collection c):

        Collection c = new ArrayList();
        c.add("hello");
        c.add("world");
        c.add("java");

        Collection c1 = new ArrayList();
        c1.add("beijing");
        c1.add("shanghai");
        c1.add("shenzhen");
        
        System.out.println(c.removeAll(c1)); // false
        System.out.println(c); // [hello, world, java]
        System.out.println(c1); //[beijing, shanghai, shenzhen]

        boolean retainAll(Collection c):

        Collection c = new ArrayList();
        c.add("hello");
        c.add("world");
        c.add("java");

        Collection c1 = new ArrayList();
        c1.add("beijing");
        c1.add("shanghai");
        c1.add("shenzhen");

        System.out.println(c.retainAll(c1)); // true
        System.out.println(c); // []
        System.out.println(c1); //[beijing, shanghai, shenzhen]
 
        c1.add("hello");
        c1.add("world");
        c1.add("java");
        System.out.println(c.retainAll(c1)); // false
        System.out.println(c); // [hello, world, java]
        System.out.println(c1);
        
API::
         boolean contains(Object o)     (如果此 collection 包含指定的元素,则返回 true,否则,返回false)
         
         boolean containsAll(Collection c)(如果c中的每一个元素都在集合中存在,就返回true,否则返回false)
         
API:
    获取集合的属性:
         boolean isEmpty()              (如果此 collection 没有元素,则返回 true)
         
         int size()                     (返回此 collection 中的元素个数)
API:
    遍历:
         Object[] toArray()             (返回包含此 collection 中所有元素的数组)
         
         Iterator<E> iterator()         (返回在此 collection 的元素上进行迭代的迭代器)
例:        
        Object[] toArray():

        Collection c = new ArrayList();
        c.add("hello");
        c.add("world");
        c.add("java");
        Object[] array = c.toArray();
        for (int i = 0; i < array.length; i++) {
            String s = ((String) array[i]);
            System.out.println(s.toUpperCase());
        }

        // 修改数组不会影响到集合。
        array[2] = "javase";
        System.out.println(Arrays.toString(array)); //[hello, world, javase]
        System.out.println(c); //[hello, world, java]

        // 修改集合也不会影响到数组.
        c.add("javase");
        System.out.println(Arrays.toString(array));//[hello, world, java]
        System.out.println(c);//[hello, world, java, javase]
        
例:
         Iterator<E> iterator():

Iterator iterator()
    迭代器,集合的专用遍历方式

Iterator:
    概述:对 collection 进行迭代的迭代器,是一个接口,它依赖于集合对象存在。
    
    API:
          boolean hasNext():如果仍有元素可以迭代,则返回 true。
          E next(): 返回迭代的下一个元素。
          void remove(): 删除的是最近返回的元素

        Collection c = new ArrayList();
        c.add("hello");
        c.add("world");
        c.add("java");
        Iterator it = c.iterator();
        System.out.println(it.next()); // hello
        System.out.println(it.next()); // world
        System.out.println(it.next()); // java
        System.out.println(it.next()); // NoSuchElementException

        /*while (it.hasNext()) {
            String s = (String) it.next();
            System.out.println(s.toUpperCase());
        }*/

        while (it.hasNext()) {
            String s = (String) it.next();
            if ("world".equals(s)) {
                it.remove();
            }
        }
        System.out.println(c);//[hello, java]

使用迭代器时的注意事项:
    a. 用迭代器对集合遍历的时候,不要使用集合的API对集合进行修改,因为会发生ConcurrentModificationException
    b. 不建议使用while循环, 可以使用for循环, 最好使用foreach循环.

        Collection c = new ArrayList();
        c.add("hello");
        c.add("world");
        c.add("java");
        Iterator it = c.iterator();
        // 在遍历的过程中使用集合的API对集合进行删除"hello"操作
        //ConcurrentModificationException,操作失败
        while (it.hasNext()) {
            Object obj = it.next(); // ConcurrentModificationException
            if ("hello".equals(obj)) {
                c.remove(obj);
            }
        }
        // 在遍历的过程中使用迭代器进行删除"hello"操作,成功
        Collection c = new ArrayList();
        c.add("hello");
        c.add("world");
        c.add("java");
        
        for(Iterator it = c.iterator(); it.hasNext(); ) {
            Object obj = it.next();
            if ("hello".equals(obj)) {
                it.remove();
            }
        }
3)关于迭代器的画图说明

迭代器设计原理
迭代器的示意图
并发修改异常

2. List接口

1)概述
List extends Collection:
概述:
    它是有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。
    用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
    与 set 不同,列表通常允许重复的元素。更确切地讲,
    列表通常允许满足 e1.equals(e2) 的元素对 e1 和 e2,
    并且如果列表本身允许 null 元素的话,通常它们允许多个 null 元素。
2)特有的API
    增:
        void add(int index, E element)               (在列表的指定位置插入指定元素)
                                                     (Index范围:[0, size()])
        
        boolean addAll(int index, Collection c)      (添加指定 collection 中的所有元素到此列表的结尾,
                                                      顺序是指定 collection 的迭代器返回这些元素的顺序,
                                                      如果原List集合发生了修改,返回true, 否则返回false.)
                                                      (Index范围:[0, size()])
    查:
        E get(int index)   
        返回列表中指定位置的元素(Index范围: [0, size()-1])
        
        int indexOf(Object o)
        获取集合中第一个与指定对象o相等元素的索引,如果集合中没有和o相等的元素, 返回-1.
        
        int lastIndexOf(Object o)
        获取集合中最后一个与指定对象o相等元素的索引,如果集合中没有和o相等的元素, 返回-1.
    删:
        E remove(int index)  
        删除指定索引位置的元素, 并把被删除的元素返回(Index范围:[0, size()-1])
    改:
        E set(int index, E element)
        用element替换指定索引位置的元素,并把该位置原来的元素返回(Index范围:[0, size()-1])
    遍历:
        ListIterator<E> listIterator()
        返回此列表元素的列表迭代器。
        
        ListIterator<E> listIterator(int index)
        返回列表中元素的列表迭代器,从列表的指定位置开始。
遍历:
    ListIterator<E> listIterator()
    迭代器位于最前面
    ListIterator<E> listIterator(int index) 范围:[0, size()]
    可以指定迭代器的位置,下一个元素的索引位置为index

ListIterator extends Iterator
概述:系列表迭代器,允许程序员按任一方向遍历列表、迭代期间修改列表
      (但不可以用集合api修改,ConcurrentModificationException),
      并获得迭代器在列表中的当前位置          
API:
    boolean hasNext()
    boolean hasPrevious()
    E next()
    E previous()
    int previousIndex(): 迭代器前一个元素的索引
    int nextIndex():迭代器后一个元素的索引
    void add(E e)
    void remove():删除最近返回的元素
    void set(E e):被替换的是最近返回的元素
例:

        List list = new ArrayList();
        list.add("赵灵儿");
        list.add("王语嫣");
        list.add("小龙女");

        // 练习2:在王语嫣前面添加茜茜
        for(ListIterator it = list.listIterator(list.size()); it.hasPrevious(); ) {
            String s = (String) it.previous();
            if ("王语嫣".equals(s)) {
                it.add("茜茜");
            }
        }
        System.out.println(list);//[赵灵儿,茜茜,王语嫣,小龙女]

        // 练习3:在王语嫣前面添加茜茜(用集合的API添加)  
        for(ListIterator it = list.listIterator(list.size()); it.hasPrevious(); ) {
            String s = (String) it.previous();
            if ("王语嫣".equals(s)) {
                int index = it.nextIndex();
                list.add(index, "茜茜");//ConcurrentModificationException
            }
        }
        System.out.println(list);

        // 练习2:删除王语嫣
        for(ListIterator it = list.listIterator(); it.hasNext(); ) {
            String s = (String) it.next();
            if ("王语嫣".equals(s)) {
                it.remove();
            }
        }
        System.out.println(list);//[赵灵儿,小龙女]

        //练习2:把王语嫣替换成茜茜
        for(ListIterator it = list.listIterator(); it.hasNext(); ) {
            String s = (String) it.next();
            if ("王语嫣".equals(s)) {
                it.set("茜茜");
            }
        }
        System.out.println(list);//[赵灵儿,茜茜,小龙女]

        // 练习3:把王语嫣替换成茜茜(用集合的API)    
        for(ListIterator it = list.listIterator(); it.hasNext(); ) {
            String s = (String) it.next();
            if ("王语嫣".equals(s)) {
                int index = it.previousIndex();
                list.set(index, "茜茜");//例外,没有运行异常,可以正确执行
            }
        }
        System.out.println(list);//[赵灵儿, 茜茜, 小龙女]
        
    截取:
        List<E> subList(int fromIndex, int toIndex) Index值包左不包右
        返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
例:

        List list = new ArrayList();
        list.add("赵灵儿");
        list.add("王语嫣");
        list.add("小龙女");
        List subList = list.subList(1, 2);
        System.out.println(subList);  //[王语嫣]
        System.out.println(subList.size()); //1  

        subList.remove(0);
        System.out.println(subList);// []
        System.out.println(list); //[赵灵儿, 小龙女]
        //原List集合的"王语嫣"元素被删除
        //原因:sublist方法返回的新List集合,和调用该方法的List集合共享被截取的元素(视图技术),
        //新List集合删除了"王语嫣",那么原List集合中的"王语嫣"元素自然也不存在了
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值