zoukankan      html  css  js  c++  java
  • Java集合--接口

    集合

    img

    ​ Java集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有3种子类型,List、Set和Queue,再下面是一些抽象类,最后是具体实现类,常用的有ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap等等。

    ​ 集合框架是一个用来代表和操纵集合的统一架构。集合类库也是按照接口与实现分离的规范来的,整个集合框架包含三部分的内容:

    接口:是代表集合的抽象数据类型。例如Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象;

    实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap;

    算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。

    ​ 除了集合,该框架也定义了几个Map接口和类。Map里存储的是键/值对。尽管Map不是集合,但是它们完全整合在集合中。集合框架体系如图所示:

    img

    迭代器-Iterator

    Iterator

    ​ 迭代器接口一共包含四个方法:

    ​ next方法用于逐个访问集合中的每个元素,

    ​ hasNext方法用于判断当前的迭代器对象是否还有可供访问的元素,如果有就返回true;如果没有,则返回false。

    ​ 所以在使用迭代器对象访问集合中的元素时,可以借助hasNext方法和next方法进行访问,在hasNext返回true时,再执行next方法。

    iter = c.iterator()
    while(iter.hasNext()){
    	……
    }
    

    ​ 使用for-each循环可以更加简练的表示同样的循环操作:

    for(String element : c){
    	……
    }
    

    ​ for-each循环被编译器简单的翻译为带有迭代器的循环。

    ​ for-each循环可以与任何实现了Iterable接口的对象一起工作,这个接口只包含了一个抽象方法:

    Iterator<T> iterator();
    

    ​ Collection接口扩展了Iterable接口。所以对于标准类库中的任何集合都可以使用for-each循环。

    Iterable接口

    ​ 如果一个集合对象要表明自己支持迭代,可以使用foreach语句的特权,就必须实现Iterable接口,表明这个集合对象是可迭代的。这点从Iterable的源码注释中就可以看出来:

     Implementing this interface allows an object to be the target of the "for-each loop" statement. 
    

    ​ 但是实现Iterable接口,除了说明当前的类是可迭代的,还要实现了一个返回迭代器对象的方法iterator,该方法为foreach语句提供一个迭代器来进行foreach操作。那为什么要用这个接口而不直接实现Iterator接口呢?

    ​ 1、Java设计者让Collection继承于Iterable而不是Iterator接口。首先要明确的是,Iterable的子类Collection,Collection的子类List,Set等,这些是数据结构或者说放数据的地方。而实现了Iterator的类则用于定义实现迭代逻辑的对象,让迭代逻辑和数据结构分离开来,这样的好处是可以在一种数据结构上实现多种迭代逻辑。

    ​ 2、更重要的一点是:每一次调用Iterable的Iterator()方法,都会返回一个从头开始的Iterator对象,各个Iterator对象之间不会相互干扰,这样保证了可以同时对一个数据结构进行多个遍历。这是因为每个循环都是用了独立的迭代器Iterator对象。

    3、如果Collection等集合类直接实现Iterator这个接口的时候,则当我们new一个新的对象的时候,这个对象中就包含了当前迭代位置的数据(指针),当这个对象在不同的方法或者类中传递的时候,当前传递的对象的迭代的位置是不可预知的,那么我们在调用next()方法的时候也就不知道是指到那一个元素。即使设置一个重置指针的方法用来重置当前迭代的位置,这样Collection也只能同时存在一个当前迭代位置的对象,而不能对一个集合对象同时进行多个遍历。所以不能直接选择实现Iterator。

    List接口的源码:

    ArrayList的源码:

    ​ 可以看到List没有直接实现Iterator接口,它的具体实现是在一个具体的集合类中定义一个内部类,然后再iterator方法中返回这个内部类对象。这样就能保证,每次调用iterator对象,都能返回一个新的迭代器对象了,迭代器之间也就不会有干扰了。

    ​ Iterable接口还有一个方法,那就是spliterator方法,该方法返回一个返回Spliterator迭代器,该迭代器叫做可分割迭代器(splitable iterator),Spliterator就是为了并行遍历元素而设计的一个迭代器,jdk1.8中的集合框架中的数据结构都默认实现了spliterator。

    default Spliterator<T> spliterator() {
            return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
    

    Collection集合

    ​ Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。Collection接口存储一组不唯一,无序的对象。Collection可以主要分为set、List 、Queue三种类型。

    ​ 其主要方法如下:

    1、添加方法
     boolean add(Object obj)	  : 添加一个对象
     boolean addAll(Collection c) : 添加一个集合的对象
    2、删除方法
     void clear() 移除所有对象
     boolean remove(Object) 移除一个对象
     boolean removeAll(Collection c) 移除一个集合的对象,只要有一个对象移除了,就返回true
    3、判断方法
     boolean contains(Object o) 判断集合是否包含该对象
     boolean containsAll(Collection c) 判断集合中是否包含指定的集合对象,只有包含所有的对象,才返回 true。
     boolean isEmpty() 判断集合是否为空。
    4、获取方法
     Iterator<E> iterator() 迭代器
    5、长度功能
     int size() 对象个数
    6.交集功能
     boolean retainAll(Collection c) 移除此 Collection 中未包含在指定Collection 中的所有对象,简单说就是,集合1和集合2进行对比,最终结果保存在集合1 ,返回值表示的是 A是否发生变化。
    7.转换为数组
     Object[] toArray() 返回这个集合的对象数组
     <T> T[] toArray(T[] a)  返回这个集合的对象数组。如果a足够大,就将集合中的元素填入这个数组中。剩余空间填补null;否则分配一个新数组,其成员类型与a的成员类型相同,其长度等于集合的大小,并填充集合元素。
    Java 8 新方法:
     boolean removeif(Predicate filter) 按照一定规则过滤集合中的对象。Predicate用于判断对象是否符合某个条件。
    

    List

    ​ List接口是一个有序的Collection,使用此接口能够精确的控制每个元素插入的位置。可以采用两种方式访问元素:一种是随机访问,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的任意元素,第一个元素的索引为0,而且允许有相同的元素;第二种方式是使用迭代器访问,此种方式必须是顺序地访问元素。

    ​ List接口定义了多个用于随机访问的方法:

    E get(int index);
    E set(int index, E element);
    void add(int index, E element);
    

    ​ List接口还有一个方法会返回一个ListIterator对象,ListIterator是Iterator的子接口,可以双向遍历集合,同时定义了一个add方法,用于在迭代器位置前面增加一个元素。

    ​ 在List的具体实现中,有两种有序的集合,它们在性能开销上有很大差异。由数组支持的有序集合可以快速地随机访问,因此适合使用List方法并提供一个整数索引来访问。与之不同的是,链表尽管也是有序的,但是随机访问很慢,所以最好使用迭代器来访问。

    Set

    ​ Set 具有与Collection完全一样的接口,只是行为上不同,Set不保存重复的元素。Set接口存储一组唯一,无序的对象。

    Queue

    ​ 队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作。

    Map集合

    ​ Map 接口存储一组键值对象,提供key(键)到value(值)的映射。

    参考:https://www.runoob.com/java/java-collections.html
    https://www.cnblogs.com/bkyxnc/p/10460199.html

  • 相关阅读:
    死锁及预防
    Java中的接口和抽象类
    Jmeter执行java脚本结束时提示:The JVM should have exited but did not.
    dubbo服务的group和version
    Dubbo-admin无法显示Group分组信息
    Python中的变量、引用、拷贝和作用域
    记一次调试python内存泄露的问题
    使用gdb调试python程序
    dstat用法;利用awk求dstat所有列每列的和;linux系统监控
    flask到底能登录多少用户?
  • 原文地址:https://www.cnblogs.com/yxym2016/p/14508583.html
Copyright © 2011-2022 走看看