Collection容器家族(Iterable接口、Collection接口、List接口、Set接口)

版权声明:菜鸟的蜕变 https://blog.csdn.net/IdealSpring/article/details/81739685

一、什么是接口? 

        接口中定义的是该继承体系中的扩展功能。

举个例子:(猫狗案例)

        狗一般就是看门,猫一般就是作为宠物了。但是,现在有很多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。而这些额外的动作,并不是所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的。所以,这些额外的动作定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。所以,为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可。

二、Iterable接口

1.在collection集合体系中位置及作用

        处于顶层 ,作为最基础的接口。

        实现此接口,可以通过iterator迭代器遍历整个集合。

2.Iterable接口中的方法

    Iterator<T>  iterator();        // 返回一个在一组 T 类型的元素上进行迭代的迭代器。

    Iterable只是返回了Iterator接口的一个实例,为什么不把两个接口合二为一,直接在Iterable里面定义hasNext(),next()等方法。是因为实现了Iterable的类可以在实现多个Iterator内部类,例如LinkedList中的ListItr和DescendingIterator两个内部类,就分别实现了双向遍历和逆序遍历。通过返回不同的Iterator实现不同的遍历方式,这样更加灵活。如果把两个接口合并,就没法返回不同的Iterator实现类了。

JDK1.8中新加了两个方法:

    default void forEach(Consumer<? super T> action);    // 对集合使用foreach()遍历。

  forEach()的使用方法(如图):

    /**
     * 使用forEach()遍历集合
     * 
     * @param list  要遍历的集合
     */
    public static void printList(List<Integer> list) {
        /**
        * num可以任意指定,在只作为变量存储遍历出来的元素(单个元素)
        */
        list.forEach(num -> System.out.println(num));
    }

    default Spliterator<T> spliterator();    // //并行迭代器

    Spliterator是一个可分割迭代器(splitable iterator),可以和iterator顺序遍历迭代器一起看。可以通过 tryAdvance() 方法逐个遍历,也可以按照 forEachRemaining() 方法进行按 bulk 逐块的遍历。(内部调用的还是tryAdvance)。使用tryAdvance()方法遍历时内部同时做了 hasNext() 以及 next() 的工作。Spliterator中常用的方法有:tryAdvance()、forEachRemaining()、trySplit()等。

三、Collection接口

1.在Collection集合体系中的位置及作用

         出去Iterable接口,它是集合体系中的最底层接口,所有其实现类,子接口都必须实现或继承它的方法。同时改接口规范了不管是线性表(数组和链表)、队列、Hash和树结构集合子类所要实现的共性方法。所有其实现类,在此约束和接口进行实现。

2.Collection的功能概述

   添加功能
           boolean add(Object obj):添加一个元素
           boolean addAll(Collection c):添加一个集合的元素
   删除功能
           void clear():移除所有元素
           boolean remove(Object o):移除一个元素
           boolean removeAll(Collection c):移除一个集合的元素(是一个还是所有)
   判断功能
           boolean contains(Object o):判断集合中是否包含指定的元素
           boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(是一个还是所有)
           boolean isEmpty():判断集合是否为空
   获取功能
           Iterator<E> iterator()(重点)
   长度功能
           int size():元素的个数
           面试题:数组有没有length()方法呢?字符串有没有length()方法呢?集合有没有length()方法呢?
   交集功能
           boolean retainAll(Collection c):两个集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢?
   把集合转换为数组(更多https://blog.csdn.net/IdealSpring/article/details/81475811)
           Object[] toArray()

           <T> T[] toArray(T[] a) 

以上是Collection中最基本的方法,JDK1.8之后新引入方法:

    default boolean removeIf(Predicate<? super E> filter)             //删除满足给定条件的集合的所有元素

        Collection<Integer> c = new ArrayList<>();
        c.add(1);
        c.add(2);
        c.add(3);
        c.add(4);
        c.add(5);

        /**
         * removeIf(Predicate<? super E> filter)的Predicate类型参数属于函数式接口(在类上明确标注了@FunctionalInterface)
         * 传入的 x -> x % 2 == 0 是Lambda表达式创建的(过滤掉余数为0的)。
         * 其实质是Predicate接口的匿名内部类
         */
        c.removeIf(x -> x % 2 == 0);
        System.out.println(c);

    default Spliterator<E> spliterator()            //并行迭代器   ---这个方法是继承自Iterable接口,使用见上文。

    default Stream<E> stream()                     //返回该流的对象(见:https://blog.csdn.net/IdealSpring/article/details/81773750)

    default Stream<E> parallelStream()        //并行流,我们可以很容易的对数据进行并行操作

    Spliterator是一个可分割迭代器(splitable iterator,见名知意了吧)。jdk1.8发布后,对于并行处理的能力大大增强,Spliterator就是为了并行遍历元素而设计的一个迭代器,jdk1.8中的集合框架中的数据结构都默认实现了spliterator。

    Stream是元素的集合,这点让Stream看起来用些类似Iterator;可以支持顺序和并行的对原Stream进行汇聚的操作;我们这里不详细的介绍Stream流的具体含义以及使用方式和使用它的好处,大家就暂且把它当作一个高效的Iterator好了,我们把对集合的操作变成了对流的操作。

四、List接口

在Collection集合体系中的位置及作用

        Collection集合家族体系中共有量大分支,List和Set。List是基于线性表结构的分支。List接口继承了Collection接口,除了拥有父接口的功能外,额外还扩展了自己的一些方法。

   List集合的特有功能:
   A:添加功能
           void add(int index,Object element):在指定位置添加元素
           void add(int index, Collection<? extends E> c):在index位置添加指定集合中所有元素
   B:获取功能
           Object get(int index):获取指定位置的元素
           int indexOf(Object o):元素第一个出现的位置
        int lastIndexOf(Object o):元素最后一次出现的位置
   C:列表迭代器
           ListIterator listIterator():List集合特有的迭代器
           ListIterator<E> listIterator(int index):从固定位置开始返回一个listiterator
           List<E> subList(int fromIndex, int toIndex):返回一个当前集合的视图  从fromindex开始toindex结束
   D:删除功能
           Object remove(int index):根据索引删除元素,返回被删除的元素
   E:修改功能
           Object set(int index,Object element):根据索引修改元素,返回被修饰的元素

JDK1.8中新添加的功能: 

        default Spliterator<E> spliterator()                    //1.8新增并行遍历迭代器

        default void replaceAll(UnaryOperator<E> operator)        //1.8新增替换方法

        default void sort(Comparator<? super E> c)         //1.8新增排序方法内部实现Arrays.sort(a, (Comparator) c)

        List接口规范了基于线性表存储结构的集合,线性表具体划分又可以分成数组和链表,List的子类ArrayList是基于数组结构实现的集合、LinkedList是基于链表结构的实现类集合。还有一个Vector集合,由于底层数据结构是数组,查询快,增删慢。线程安全,效率低等特点,我们在实际开发中基本很少会使用。

五、Set接口

在Collection体系中的位置

     set接口和list接口一样,继承了Collection接口。其中拥有collection接口中的方法之外,并没有扩展其他的方法。其主要实现类有HashSet和TreeSet,在HashSet的基础上又延伸出了LinkedHashSet,面试中可能会问到的问题也就只有HashSet和TreeSet各自的实现方式,是否有序,LinkedHashSet和HashSet之间有什么区别,扩展出了什么有什么优势等。

    总之Collection这一大规范下划分出了两个小规范,一个是线性表规范,另一个是Set的规范,各自有各自体系的用途,对于我们日后从事优化,开发软件,设计框架等一系列操作时,在选择数据结构,也就是选择容器的使用时必须考虑我到底该用什么,用哪个好一些,考虑是时间效率重要还是空间效率重要等一系列延伸出来的问题。

猜你喜欢

转载自blog.csdn.net/IdealSpring/article/details/81739685