zoukankan      html  css  js  c++  java
  • Collection容器家族(Iterable接口、Collection接口、List接口、Set接口)

    一、什么是接口? 

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

    举个例子:(猫狗案例)

            狗一般就是看门,猫一般就是作为宠物了。但是,现在有很多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。而这些额外的动作,并不是所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的。所以,这些额外的动作定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。所以,为了体现事物功能的扩展性,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的规范,各自有各自体系的用途,对于我们日后从事优化,开发软件,设计框架等一系列操作时,在选择数据结构,也就是选择容器的使用时必须考虑我到底该用什么,用哪个好一些,考虑是时间效率重要还是空间效率重要等一系列延伸出来的问题。

  • 相关阅读:
    【Henu ACM Round#15 F】Arthur and Questions
    【Henu ACM Round#16 F】Om Nom and Necklace
    【Henu ACM Round#16 E】Paths and Trees
    JS制作的简单的三级及联
    .Net实现的批量删除(使用了repeater控件)
    setInterval和setTimeout调用方法小知识科普
    AJAX制作JSON格式的实时更新数据的方法
    关于获取网站域名的写法杂谈
    JS初识(着重讲解Date函数)
    Guid函数
  • 原文地址:https://www.cnblogs.com/IdealSpring/p/11871210.html
Copyright © 2011-2022 走看看