Collection接口是java.util包中一个非常重要的接口,除此之外还包括很多其他的接口,详细内容可以查看集合框架 的集合接口部分内容。
java.util包中的集合类就像一个装有多个对象的容器,而不同的容器有不同的特性,适用于不同的情况,其中数组和集合的区别就在于:数组的长度是固定的,而集合的长度是可变的;数组既可以存放基本数据类型也可以存对象,集合只能存储对象。常见的集合类包括List集合、Set集合、Map集合等,其中List和Set继承Collection接口。
JDK不提供Collection接口的任何直接实现,而是提供更合适的子接口(如Set或List)的实现。Collection接口通常用于传递集合,并在需要最大通用性的地方操作它们。这些被传递的集合,可能是无序的,也有可能是有序的;一些集合允许有重复元素,而另一些不允许。因此我们要处理的集合可能具有不同的特性,根据集合中元素的特征及想要实现的目标的不同,我们需要使用不同的子接口来间接的实现Collection,这些子接口类就被称为「实现类」。
一、Collection接口的常用方法及说明
Set接口和List接口都继承Collection接口,Collection接口虽然不能直接被使用,但是提供了操作集合以及集合中元素的方法,且Set接口和List接口都可以调用Collection接口中的方法。Collection接口中的方法及说明:
方法 | 修饰符和类型 | 功能描述 |
---|---|---|
add(E e) | boolean | 将指定对象添加到当前集合内,确保集合对象中有e。 |
addAll(Collection<? extends E> c) | boolean | 将指定区间的对象添加到当前集合内。 |
clear() | void | 删除集合中所有元素。 |
contains(Object o) | boolean | 判断集合中是否包含指定元素。 |
containsAll(CCollection<? > c) | boolean | 判断集合中是否包含指定集合中的所有元素。 |
equals(Object o) | boolean | 判断集合与指定对象是否相等。 |
hashCode() | int | 返回当前集合的哈希编码。 |
isEmpty() | boolean | 返回boolean值,用于判断当前集合是否为空。 |
iterator() | Iterator<E> | 返回用于遍历集合内元素的迭代器。 |
parallelStream() | default Stream<E> | 以当前集合对象为数据源创建并行执行的流视图进行中间操作,有分而治之的思想,可以提高多线程任务的执行速度。 |
remove(Object o) | boolean | 将制定对象从当前集合中移除。 |
removeAll(Collection<? > c) | boolean | 将制定集合中的全部对象从当前集合中移除。 |
removeIf(Predicate<? super E> filter) | default boolean | 满足指定判断条件的所有对象从当前集合中移除。 |
retainAll(Collection<?> c) | boolean | 仅保留和指定集合相同的元素,即删除与指定集合不相同的元素。 |
size() | int | 返回int型值,获取当前集合中元素的个数。 |
spliterator() | default Spliterator<E> | 在当前集合元素基础上创建分割器。参考Spliterator接口的spliterator()方法。 |
stream() | default Stream<E> | 以当前集合对象为数据源创建视图进行中间操作,中间操作不改变数据源。 |
toArray() | Object[] | 将集合转换为数组,数组包含集合中所有元素,且元素顺序一致。 |
toArray(T[ ] a) | <T> T[ ] | 将集合转换为指定类型的数组。如果无法实现强制转换,就抛出ArrayStoreException。 |
更详细的描述,请参与官方API的Interface Collection<E>部分。
二、Collection接口的子接口
1、子接口概述
子接口名称 | 描述 |
---|---|
BeanContext | BeanContext充当JavaBean的逻辑分层容器。 |
BeanContextServices | BeanContextServices接口为BeanContext提供了一种向BeanContextChild对象提供通用“服务”的机制。 |
BlockingDeque | 一个支持阻塞操作的双端队列,这些操作在检索元素时等待双端队列变为非空,并在存储元素时等待双端队列中的空间变为可用。 |
BlockingQueue | 支持在检索元素时等待队列变为非空,并在存储元素时等待队列中的空间变为可用操作的队列。 |
Deque | 支持在两端插入和删除元素的线性集合。 |
List | collection的子接口,允许有重复的元素,是有序的 .同样有三个实用类:ArrayList,LinkedList,Vector。 |
NavigableSet | 返回最接近搜索目标的匹配项,方法lower,floor,天花板和higher返回元素分别小于,小于或等于,大于或等于和大于给定元素,如果没有这样的元素,则返回null。DescendingSet方法返回一个集合的视图,可以按升序或降序访问和遍历NavigableSet。 |
Queue | 用于存放等待处理的数据的集合,其中的元素一般采用FIFO(先进先出)的顺序,也有以元素的值进行排序的优先序列。 |
Set | 是collection的子接口,不能包含重复的元素。Set接口没有引入新的方法,即它所有的方法都是继承了父类collection中的方法。 Set中有三个实用类:HashSet,TreeSet,LinkedHashSet。 |
SortedSet | 是一个特殊的set接口,它同样是有序的。sortedset接口为set接口的视图(子集)和它的两端(即头和尾)提供了访问方法。添加到sortedset实现类的元素必须实现Comparable接口,否则必须给它的构造函数提供一个Comparable接口的实现。Treeset类是它的唯一实现。 |
TransferQueue | TransferQueue继承了BlockingQueue(``BlockingQueue又 继承了Queue )并扩展了一些新方法。BlockingQueue(是指这样的一个队列:当生产者向队列添加元素但队列已满时,生产者会被阻塞;当消费者从队列移除元素但队列为空时,消费者会被阻塞。 |
2、集合框架中常用接口的继承关系
常见的集合类包括Set、List和Map,但是Map。List和Set都是继承Collection接口的,但是Map接口并不是,他是直接在java.util包中的接口。但是Map依然被看作是Collection框架的一部分。
(1)常用接口及继承关系
(2)常用集合接口及常用实现类
三、Collection接口的实现类
Java提供了一套实现了Collection接口的标准集合类。这这些类通常是指通过任意一个子接口间接实现Collection的集合类。其中一些是具体类,这些类可以直接拿来使用,而另外一些是抽象类,提供了接口的部分实现。
实现类 | 描述 |
---|---|
AbstractCollection | 实现了大部分的集合接口。 |
AbstractList | 继承于AbstractCollection并且实现了大部分List接口。实现了对数据元素的随机访问。 |
AbstractQueue | 继承于AbstractCollection并实现了大部分Queue(队列)接口 |
ArrayDeque | 继承于AbstractCollection,实现了Queue接口,实现了可调整大小的数组。提供的双端对类没有容量限制。不是线程安全的,不支持多线程访问,禁止空元素。在用作堆时性能高于Stack,用作Queue时,性能高于LinkedList。 |
ConcurrentLinkedDeque | 是双向链表结构的无界并发队列,相当于一个双向链表。在执行并发插入,删除和访问操作可以跨多个线程安全执行。禁止空元素。使用了自旋+CAS的非阻塞算法来保证线程并发访问时的数据一致性。迭代器是弱一致性的。 |
AbstractSequentialList | 继承于AbstractList并且提供了对数据元素的链式访问(而不是随机访问)。 |
AbstractSet | 继承于AbstractCollection并实现了大部分Set接口。 |
ArrayBlockingQueue | 继承自AbstractBlockingQueue,是一个基于数组的有界的阻塞队列,间接的实现了Queue接口和Collection接口。底层以数组的形式保存数据(实际上可看作一个循环数组)。常用的操作包括 add,offer,put,remove,poll,take,peek。 |
ArrayList | 实现了List接口,实现了可变大小的数组,随机访问和遍历元素时,提供更高的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList插入删除效率很低。 |
AttributeList | 继承ArrayList,表示MBean的属性值的列表。可以是类型安全的,添加非属性对象时将产生IIIegalArgumentException异常。 |
LinkedList | 实现了List接口,允许有null元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时构建一个同步的List。LinkedList的随机访问效率极低。 |
BeanContextSupport | 该帮助器类提供java.beans.beancontext.BeanContext接口的实用程序实现。由于此类直接实现BeanContext接口,因此可以并且可以通过对该实现进行子类化或通过对该类的实例从另一个实例的临时委派来使用该类。 |
BeanContextServicesSupport | 继承BeanContextSupport,功能类似 |
ConcurrentHashMap.KeySetView | ConcurrentHashMap作为一组键的视图,其中可以选择通过映射到公共值来启用添加。 此类不能直接实例化。 可参阅keySet(),keySet(V),newKeySet(),newKeySet(int)。 |
ConcurrentLinkedQueue | ConcurrentLinkedDeque 是双向链表结构的无界并发队列。使用CAS实现并发安全,与 ConcurrentLinkedQueue 的区别是该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除)。适合“多生产,多消费”的场景。内存一致性遵循对 ConcurrentLinkedDeque 的插入操作先行发生于(happen-before)访问或移除操作。相较于 ConcurrentLinkedQueue,ConcurrentLinkedDeque 由于是双端队列,所以在操作和概念上会更加复杂。 |
ConcurrentSkipListSet | 是线程安全的有序的集合,适用于高并发的场景。和TreeSet虽然都是有序的集合。但是它们的线程安全机制不同,TreeSet是非线程安全的,而ConcurrentSkipListSet是线程安全的。并且,ConcurrentSkipListSet是通过ConcurrentSkipListMap实现的,而TreeSet是通过TreeMap实现的。 |
CopyOnWriteArrayList | 是一个ArrayList的线程安全的变体,其原理大概可以通俗的理解为:初始化的时候只有一个容器,很常一段时间,这个容器数据、数量等没有发生变化的时候,大家(多个线程),都是读取(假设这段时间里只发生读取的操作)同一个容器中的数据,所以这样大家读到的数据都是唯一、一致、安全的,但是后来有人往里面增加了一个数据,这个时候CopyOnWriteArrayList 底层实现添加的原理是先copy出一个容器(可以简称副本),再往新的容器里添加这个新的数据,最后把新的容器的引用地址赋值给了之前那个旧的的容器地址,但是在添加这个数据的期间,其他线程如果要去读取数据,仍然是读取到旧的容器里的数据。 |
CopyOnWriteArraySet | 它是线程安全的无序的集合,可以将它理解成线程安全的HashSet。有意思的是,CopyOnWriteArraySet和HashSet虽然都继承于共同的父类AbstractSet;但是,HashSet是通过“散列表(HashMap)”实现的,而CopyOnWriteArraySet则是通过“动态数组(CopyOnWriteArrayList)”实现的,并不是散列表。和CopyOnWriteArrayList类似,其实CopyOnWriteSet底层包含一个CopyOnWriteList,几乎所有操作都是借助CopyOnWriteList,就像HashSet包含HashMap |
DelayQueue | DelayQueue是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。这种队列是有序的,即队头对象的延迟到期时间最长。注意:不能将null元素放置到这种队列中。 |
EnumSet | EnumSet 是一个专为枚举设计的集合类,EnumSet中的所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式或隐式地指定。集合元素时有序的,内部以位向量的形式存储,不允许null元素。 |
HashSet | 实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但是最多只能有一个null元素。 |
JobStateReasons | JobStateReasons 类是打印属性类,它是一个枚举值集合,提供了有关作业当前状态的额外信息,即扩充作业的 JobState属性值的信息。 |
LinkedBlockingDeque | LinkedBlockingDeque是一个由链表结构组成的双向阻塞队列,即可以从队列的两端插入和移除元素。双向队列因为多了一个操作队列的入口,在多线程同时入队时,也就减少了一半的竞争。相比于其他阻塞队列,LinkedBlockingDeque多了addFirst、addLast、peekFirst、peekLast等方法,以first结尾的方法,表示插入、获取获移除双端队列的第一个元素。以last结尾的方法,表示插入、获取获移除双端队列的最后一个元素。LinkedBlockingDeque是可选容量的,在初始化时可以设置容量防止其过度膨胀,如果不设置,默认容量大小为Integer.MAX_VALUE。 |
LinkedBlockingQueue | 实现了BlockingQueue接口,内部基于链表来存放元素,它如果不指定容量,默认为Integer.MAX_VALUE ,也就是无界队列。为了避免队列过大造成机器负载或者内存爆满的情况出现,我们在使用的时候建议手动传一个队列的大小 |
LinkedHashSet | LinkedHashSet是Set集合的一个实现,具有set集合不重复的特点,同时具有可预测的迭代顺序,也就是我们插入的顺序。并且linkedHashSet是一个非线程安全的集合。如果有多个线程同时访问当前linkedhashset集合容器,并且有一个线程对当前容器中的元素做了修改,那么必须要在外部实现同步保证数据的冥等性。 |
LinkedTransferQueue | LinkedTransferQueue是一个由链表结构组成的无界阻塞TransferQueue队列。相对于其他阻塞队列,LinkedTransferQueue多了tryTransfer和transfer方法,采用一种预占模式,是ConcurrentLinkedQueue、SynchronousQueue(公平模式下转交元素)、LinkedBlockingQueue(阻塞Queue的基本方法)的超集。不仅仅综合了这几个类的功能,同时也提供了更高效的实现。 |
PriorityBlockingQueue | priorityBlockingQueue是一个无界队列,它没有限制,在内存允许的情况下可以无限添加元素;它又是具有优先级的队列,是通过构造函数传入的对象来判断,传入的对象必须实现comparable接口。 |
PriorityQueue | 是基于优先堆的一个无界队列,优先队列不允许空值,而且不支持non-comparable(不可比较)的对象,优先队列的头是基于自然排序或者Comparator排序的最小元素。优先队列的大小是不受限制的,但在创建时可以指定初始大小 |
RoleList | 表示角色列表(Role objects)。在创建关系和试图在关系中设置多个角色时(通过setRoles()方法),它作为RoleResult的一部分返回,以提供成功检索的角色。 |
RoleUnresolvedList | 继承Arrayist,RoleUnresolvedList表示RoleUnresolved对象的列表,表示由于尝试访问(读取或写入)角色时遇到的问题而无法从关系中检索到的角色。 |
Stack | 继承Vector,表示对象的后进先出(LIFO)堆栈。 它通过五个操作扩展了Vector类,这些操作允许将矢量视为堆栈。 提供了通常的推入和弹出操作,以及一种窥视堆栈顶部项目的方法,一种用于测试堆栈是否为空的方法以及一种用于在堆栈中搜索项目并发现其距离的方法。 从顶部开始。首次创建堆栈时,它不包含任何项目。Deque接口及其实现提供了一组更完整和一致的LIFO堆栈操作,优先使用Deque类。 |
SynchronousQueue | 类实现了BlockingQueue 接口,是一个内部只能包含一个元素的队列。插入元素到队列的线程被阻塞,直到另一个线程从队列中获取了队列中存储的元素。同样,如果线程尝试获取元素并且当前不存在任何元素,则该线程将被阻塞,直到线程将元素插入队列。将这个类称为队列有点夸大其词。这更像是一个点。 |
TreeSet | 继承AbstractSet,基于TreeMap的NavigableSet实现。 元素使用其自然顺序或在集合创建时提供的Comparator进行排序,具体取决于所使用的构造函数。此实现为基本操作(添加,删除和包含)提供了保证的log(n)时间成本。 |
Vector | Vector类实现可增长的对象数组。 像数组一样,它包含可以使用整数索引访问的组件。 但是,Vector的大小可以根据需要增大或缩小,以适应在Vector创建之后添加和删除项目。每个向量都尝试通过维持一个Capacity和一个CapacityIncrement来优化存储管理。 容量始终至少与向量大小一样大; 它通常较大,因为将分量添加到向量中时,向量的存储量会按容量增加的大小成块增加。 应用程序可以在插入大量组件之前增加向量的容量。 减少了增量重新分配的数量。 |
所有Collection实现类都应该提供两个标准构造函数:
- Void(无参数)构造函数:用于创建一个空集合
- 类型为单个参数的构造函数集合:用于创建一个新集合,其元素与其参数相同。允许用户复制任何集合,从而生成所需要实现类型的等效集合。
四、java.util包中定义的与集合相关的类
类名 | 描述 |
---|---|
Vector | 和ArrayList非常相似,但是Vector类是同步的,可以在多线程的情况下使用,允许设置默认的增长长度,默认扩容方式为原来的2倍。 |
Stack | 栈是Vector的一个子类,它实现了一个标准的后进先出的栈。 |
Dictionary | 是一个抽象类,用来存储键值对,作用和Map相似。 |
Hashtable | 是Dictionary的一个子类。 |
Properties | 继承于Hashtable,表示一个持续的属性集,属性列表中每个键及其对应值都是一个字符串。 |
BitSet | 一个BitSet类创建一种特殊类型的数组来保存位置。BitSet中数组大小会随需要增加。 |
LinkedListSet | 具有可预知可迭代顺序的Set接口的哈希表和链表的实现。 |
AbstractMap | 实现了大部分的Map接口。 |
HashMap | 实现了Map接口,根据HashCode值存储数据,具有很快的访问速度,允许存储一个键为null的对象,不支持线程同步。HashMap是一个散列表,存储的是键值对(key-value)映射。 |
TreeMap | 继承AbstractMap类,并且使用一棵树 |
WeakHashMap | 继承AbstractMap类,使用弱密钥的哈希表。 |
LinkedHashMap | 继承HashMap类,使用元素的自然顺序对元素进行排序。 |
IdentityHashMap | 继承AbstractMap类,比文档时使用引用相等。 |