美文网首页
集合 Collection接口

集合 Collection接口

作者: DOB_8199 | 来源:发表于2021-02-05 23:51 被阅读0次

    集合框架的概述

    集合、数组都是对多个数据进行存储操作的结构,简称Java容器。

    说明

    此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt,.jpg,.avi,数据库中)

    背景

    1. 数组在存储多个数据方面的特点:

           > 一旦初始化以后,其长度就确定了。

           > 数组一旦定义好,其元素的类型也就确定了。我们也就只能操作指定类型的数据了。

              比如:String[] arr; int[] arr1; Object[] arr2;

    2. 数组在存储多个数据方面的缺点:

           > 一旦初始化以后,其长度就不可修改。

           > 数组中提供的方法非常有限,对于添加、删除、插入数据等操作,非常不便,同时效率不高。

           > 获取数组中实际元素的个数的需求,数组没有现成的属性或方法可用

           > 数组存储数据的特点:有序、可重复。对于无序、不可重复的需求,不能满足。

    集合使用场景

    集合的使用场景


    集合框架

    *      |----Collection接口:单列集合,用来存储一个一个的对象

    *          |----List接口:存储有序的、可重复的数据。      --> 又称为“动态”数组 (长度可修改)

    *              |----ArrayList、LinkedList、Vector

    *          |----Set接口:存储无序的、不可重复的数据      -->类似于高中讲的“集合”

    *              |----HashSet、LinkedHashSet、TreeSet

       Collection接口继承树

    Collection接口继承树

    Collection接口中的方法的使用

    实例化

    (Collection是抽象方法,不能实例化,只能实例化它的子类)
    Collection coll =new ArrayList();

    方法

    1. add(Object e):

            将元素e添加到集合coll中

            coll.add("AA");

            coll.add(123);    //自动装箱

            Person p = new Person("Jerry",20);

            coll.add(p);

            coll.add(new Person("Jerry",20));

    2. size():

            获取添加的元素的个数

            System.out.println(coll.size());    // 5(上面的coll长度)

    3. addAll(Collection coll1):

            将coll1集合中的元素添加到当前的集合中

            Collection coll1 =new ArrayList();

            coll1.add(456);

            coll1.add("CC");

            coll.addAll(coll1);

            System.out.println(coll.size());    //7

    4. clear():

            清空集合元素

            coll.clear();

    5. isEmpty():

            判断当前集合是否为空

            System.out.println(coll.isEmpty());    // true

    6. contains(Object obj):

            判断当前集合中是否包含obj

            我们在判断时会调用obj对象所在类的equals()。

            boolean contains = coll1.contains(456);    //true

            System.out.println(coll1.contains(new String("CC")));    //true

            coll1.add(new Person("Jerry",20)));

            System.out.println(coll1.contains(new Person("Jerry",20)));    //false

             (要变成true则重写toString方法,要比较的对象处于第几个object,就调用多少个toString方法去对比)

    7.containsAll(Collection coll1):

            判断形参coll2中的所有元素是否都存在于当前集合中。

            Collection coll2 = Arrays.asList(123,4567);

            System.out.println(coll1.containsAll(coll2));    //false  (判断coll1中是否包含123和4567,只要有一个不包含就返回false)

    8. remove(Object obj):

            从当前集合中移除obj元素。

            Collection coll =new ArrayList();

            coll.add(123);

            coll.add(456);

            coll.add(new Person("Jerry",20));

            coll.add(new String("Tom"));

            coll.add(false);

            coll.remove(new String("Tom")); 

            System.out.println(coll);    // [123, 456, Person{name='Jerry', age=20}, false]

    9. removeAll(Collection coll1):

            差集:从当前集合中移除coll1中所有的元素。

            Collection coll1 = Arrays.asList(123,4567);

            coll.removeAll(coll1);

            System.out.println(coll);    //[456, Person{name='Jerry', age=20}, false]

    10. retainAll(Collection coll2):

            交集:获取当前集合和coll2集合的交集,并返回给当前集合

            Collection coll2 = Arrays.asList(123,456,789);

            coll.retainAll(coll2);

            System.out.println(coll);    // 456

    11. equals(Object obj):

            要想返回true,需要当前集合和形参集合的元素都相同,与顺序无关

    12. hashCode():

            返回当前对象的哈希值

    和数组之间相互转换

    1. 集合 --->数组:

        toArray()

        Object[] arr = coll.toArray();

    2. 数组 --->集合:

        调用Arrays类的静态方法asList()

        List list = Arrays.asList(new String[]{"AA", "BB", "CC"});

        System.out.println(list);    // [AA,BB,CC]

        注意如下写法只能识别为一个元素:

        List arr1 = Arrays.asList(new int[]{123, 456});

        System.out.println(arr1.size());//1

        应改为以下写法:

        List arr2 = Arrays.asList(new Integer[]{123, 456});

        System.out.println(arr2.size());//2

    iterator迭代器接口:

    用于遍历Collection集合元素。使用迭代器Iterator接口

    内部的方法

    next():

    方式一:

            Collection coll =new ArrayList();

            coll.add(123);

            coll.add(new Person("Jerry",20));

            Iterator iterator = coll.iterator();

            System.out.println(iterator.next());    // 123    

            System.out.println(iterator.next());    // Person{name='Jerry', age=20}

            System.out.println(iterator.next());    // 报异常:NoSuchElementException

    方式二:

            for(int i = 0;i < coll.size();i++){

                System.out.println(iterator.next());}

    hasNext() 

    判断是否还有下一个元素

            while(iterator.hasNext()){

                    System.out.println(iterator.next());}     //①指针下移  ②将下移以后集合位置上的元素返回

            ❌ 错误写法一:

            指针下移两次,检查第一个,输出第二个

            Iterator iterator = coll.iterator();

              while((iterator.next()) != null){

                  System.out.println(iterator.next());}

            ❌ 错误写法二

            集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。

            while (coll.iterator().hasNext()){

            System.out.println(coll.iterator().next());}

    remove()

    内部定义了remove(),可以在遍历的时候,删除集合中的元素。此方法不同于集合直接调用remove()

            Iterator iterator = coll.iterator();

                    while (iterator.hasNext()){    //如果有下一个元素,则返回true

                        Object obj = iterator.next();

                        if("Tom".equals(obj)){        // 如果集合中找到Tom

                            iterator.remove();}}        // 则移除

            iterator = coll.iterator();    // 遍历集合,必须重新得到一个全新的迭代器对象(指针移到初始位置)

            while (iterator.hasNext()){

                    System.out.println(iterator.next());}}

    ⚠️ 如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,再调用remove都会报IllegalStateException。

    ⚠️ 集合对象每次调用iterator()方法都得到一个全新的迭代器对象

    ⚠️ 默认游标都在集合的第一个元素之前。

    Foreach

    jdk 5.0 新增了foreach循环,用于遍历集合、数组,内部仍然调用了迭代器。

    格式:for(集合元素的类型 局部变量 : 集合对象)

        遍历集合

            for(Object obj : coll){

            System.out.println(obj);}

        遍历数组

            int[] arr =new int[]{1,2,3,4,5,6};

            //for(数组元素的类型 局部变量 : 数组对象)

            for(int i : arr){

            System.out.println(i);}

    ⚠️  使用增强for循环赋值,不会改变arr的值,只是将arr的值赋给了i,i做了改变

            for(String i : arr){

                i ="AA";}

            for (String i : arr){

                System.out.println(i);}

    Collection子接口

    List接口

    通常用来替代数组,List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引

    List接口框架

        |----Collection接口:单列集合,用来存储一个一个的对象

              |----List接口:存储有序的、可重复的数据。  -->“动态”数组,替换原有的数组

                      |----ArrayList:作为List接口的主要实现类;线程不安全的,效率高;底层使用Object[] elementData存储

                      |----LinkedList:对于频繁的插入、删除操作,使用此类效率比ArrayList高;底层使用双向链表存储

                      |----Vector:作为List接口的古老实现类;线程安全的,效率低;底层使用Object[] elementData存储

    源码分析

    ArrayList

            jdk 7情况下

           ArrayList list = new ArrayList();//底层创建了长度是10的Object[]数组elementData

           list.add(123);//elementData[0] = new Integer(123);

           ...

           list.add(11);//如果此次的添加导致底层elementData数组容量不够,则扩容。

           默认情况下,扩容为原来的容量的1.5倍,同时需要将原有数组中的数据复制到新的数组中。

           结论:建议开发中使用带参的构造器:ArrayList list = new ArrayList(int capacity)

            jdk 8中ArrayList的变化:

           ArrayList list = new ArrayList();//底层Object[] elementData初始化为{}.并没有创建长度为10的数组

           list.add(123);//第一次调用add()时,底层才创建了长度10的数组,并将数据123添加到elementData[0]

           ...

           后续的添加和扩容操作与jdk 7 无异。

        小结

            jdk7中的ArrayList的对象的创建类似于单例的饿汉式,而jdk8中的ArrayList的对象的创建类似于单例的懒汉式,延迟了数组的创建,节省内存。

    LinkedList

    LinkedList list = new LinkedList(); 内部声明了Node类型的first和last属性,默认值为null

           list.add(123);//将123封装到Node中,创建了Node对象。其中,Node定义为:体现了LinkedList的双向链表的说法

           private static class Node<E> {

                E item;

                Node<E> next;

                Node<E> prev;

           Node(Node<E> prev, E element, Node<E> next) {

                this.item = element;

                this.next = next;

                this.prev = prev; }}

    Vector

            jdk7和jdk8中通过Vector()构造器创建对象时,底层都创建了长度为10的数组。

           在扩容方面,默认扩容为原来的数组长度的2倍。

    方法的使用

    ArrayList

    void add(int index, Object ele):在index位置插入ele元素

    boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来

    Object get(int index):获取指定index位置的元素

    int indexOf(Object obj):返回obj在集合中首次出现的位置

    int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置

    Object remove(int index):移除指定index位置的元素,并返回此元素

    Object set(int index, Object ele):设置指定index位置的元素为ele

    List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合

    总结:常用方法

    增:add(Object obj)

    删:remove(int index) / remove(Object obj)

    改:set(int index, Object ele)

    查:get(int index)

    插:add(int index, Object ele)

    长度:size()

    遍历: ① Iterator迭代器方式

                ② 增强for循环

                ③ 普通的循环

    相关文章

      网友评论

          本文标题:集合 Collection接口

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