提及集合框架也是老生常谈的话题,也是面试过程当中面试官高频率问到的基础知识,新人在学习集合框架的时候老是会常常混淆这些概念和各自特性,这里简单对经常使用的几种集合作个简单总结,若有疏漏请你们多多包涵。php
首先咱们来简单了解一下Java的集合框架,如图(图片来自网络):html
Collection接口是咱们集合框架根接口对象,Collection接口为咱们定义了一系列数据集合操做,包括对集合元素的增长、删除、插入和修改以及迭代等,他的实现子类包括:
vue
![]()
AbstractCollection<E>,
AbstractList<E>,
AbstractQueue<E>,
AbstractSequentialList<E>,
AbstractSet<E>,
ArrayBlockingQueue<E>,
ArrayDeque<E>,
ArrayList<E>,
BlockingDeque<E>,
BlockingQueue<E>,
ConcurrentLinkedQueue<E>,
ConcurrentSkipListSet<E>,
CopyOnWriteArrayList<E>, and
18 others.
基本操做包括:java
|
如上图介绍:Collection接口类主要有三种实现类,Set集合、Queue集合以及最经常使用的List集合,这里须要注意一下,Map不属于Collection集合的实现类,后续会对Map集合框架进行详解,这里暂时跳过Map的介绍,android
由于咱们今天主要讲解的是List集合,这里为了加深对集合框架的理解列出此图,那么相关Set集合和Queue以及Map集合你们能够暂时先查找相关资料,这里暂时跳过。c++
List接口的具体实现类包括LinkList、ArrayList、Vector以及Stack类,如今分别对他们的使用和特性作一个简单的介绍、
es6
咱们首先看看这张图(以下),Vector类的继承关系:
web
正如上图,Vector继承自AbstractList抽象集合类,并实现了Serializable(序列化接口)、Cloneable(对象克隆接口)、List<E>抽象接口,继续追查AbstractList类咱们发现(下图):面试
AbstractList抽象类实现了List接口,并继承了AbstractCollection<E>类,npm
如上Api介绍:AbstractList接口直接实现子类有ArrayList<E>和Vector<E>,间接实现子类包括LinkedList<E>和Stack<E>,咱们今天要讲的这几个集合类都是AbstractList<E>的实现子类,那么回到正题,
Vector是List接口的实现类,支持全部的包括 adding, removing, and replacing elements在内的元素操做,底层基于数组Object[]的实现,Vector全部对元素的操做是同步的,经过加锁的方式保证数据写入的一致性,这是Vector与其余list子类最大的区别,既然底层数据结构是数组,那么咱们应该知道Vector具有数组索引快,增删慢的特性,由于增删都须要移动数组元素位置,而数组支持经过下标能够快速索引元素,时间复杂度O(1),可是增删一个元素时间复杂度为O(n-1)n。
Vector支持4种构造方法:
第一种构造方法建立一个默认的向量,默认大小为10:
Vector()复制代码
第二种构造方法建立指定大小的向量。
Vector(int size)复制代码
第三种构造方法建立指定大小的向量,而且增量用incr指定. 增量表示向量每次增长的元素数目。
Vector(int size,int incr)复制代码
第四种构造方法建立一个包含集合c元素的向量:
Vector(Collection c)复制代码
除了Collection接口定义方法外,Vector也定义了一些方法,具体请参考Api,这里不详细例举。
2.ArrayList集合介绍:
继承关系我就不贴出来了,前面已经作了详细的介绍,咱们单刀直入粗暴了解一下ArrayList一下,ArrayList的官方描述这样说:ArrayList继承自List接口,支持包括 adding, removing, and replacing elements等基于动态数组实现的集合结构,全部元素都支持,包括null。
这一点跟Vector很像,既然ArrayList底层也是基于数组实现的,那岂不是增删查的性能开销与Vector同样咯,在某种程度上来讲的确如此,他容许对元素进行快速访问,可是这里须要注意,ArrayList是线程不安全的,而Vector是线程安全的操做类,也就是说在单线程状况下ArrayList决定是你的不二选择,可是在多线程操做下咱们须要谨慎使用ArrayList集合类,避免多线程同时写而引发的数据不一致性,但实现同步须要很高的花费,所以,访问Vector比访问ArrayList慢,Vector就是由于作了这层加锁操做在使用效率上低于ArrayList性能。
除了性能开销上两者有差异,固然在其余方面也有,例如扩容,默认的扩容因子不一样,Vector默认扩展容量是原来的一倍,而ArrayList是原来的50%,具体实现请看Api.
固然ArrayList也有本身的方法,你们也能够经过看看源码ArrayList有那些实现方法以及构造函数之间的差异。
3. LinkedList集合介绍 :
一样继承关系也不贴出来,简单粗暴的了解LinkedList集合,官方这样描述的:LinkedList是List接口的实现类,支持包括增长、删除、修改、查询等操做在内的基于双链表的实现类,容许操做全部元素对象包括null。
那么LindedList集合与ArrayList、Vector集合有哪些不一样?
咱们知道后二者是基于数组实现存储的线性表结构,而LinedList底层是经过双链表实现数据存储相关操做,若是你们对链表不是很熟悉建议深刻学习一下,咱们知道链表对元素操做特性是遍历慢,增删快,不像数组基于下标的特性能够快速访问,只能从链表头指针或尾指针进行遍历操做,性能开销比较大,可是基于链表这种指针特性,能够快速进行元素增删操做,并不须要内存中元素进行复制和移动,链表结构中元素是散列储存的,而数组是线性排列的,故LinkedList很适合数据的动态插入和删除,随机访问和遍历速度则比较慢。
除了这些特性以外,另外,他还提供了List接口中没有定义的方法,专门用于操做表头和表尾元素,能够看成堆栈、队列和双向队列使用。具体方法和构造你们本身去查看Api。
4.Stack堆栈集合类:
Stack属于Vector的子类,属于堆栈集合类,属于新增的集合类,官方描述是:Stack是一种后进先出(LIFO)数据结构,它表明了一组对象。它容许用户从堆栈中弹出和推送,包括null对象。堆栈的大小没有限制。
那么既然知道它是堆栈结构,我相信你们应该对堆栈结构都了如指掌,这是咱们面向对象课程里面很重要也是很基础的知识,学过java的盆友都不会遗忘吧,若是真的记不清了要记得去补哦,
既然是堆栈结构,那么它的方法确定包括pop()和 peek()吧,入栈和出战是栈操做的最基本元素操做,固然除了这两个你们熟知的方法还有其余方法,具体也不例举你们动手查一下。
那么看到这儿今天的内容基本就结束了,最后作个小常规快速总结:
若是集合中的元素的数目大于目前集合数组的长度时,vector增加率为目前数组长度的100%,而arraylist增加率为目前数组长度的50%.如过在集合中使用数据量比较大的数据,用vector有必定的优点。
若是查找一个指定位置的数据,vector和arraylist使用的时间是相同的,都是0(1),这个时候使用vector和arraylist均可以。而若是移动一个指定位置的数据花费的时间为0(n-i)n为总长度,这个时候就应该考虑到使用Linkedlist,由于它移动一个指定位置的数据
所花费的时间为0(1),而查询一个指定位置的数据时花费的时间为0(i)。
ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增长和插入元素,都容许直接序号索引元素,可是插入数据要设计到数组元素移动 等内存操做,因此索引数据快插入数据慢,
Vector因为使用了synchronized方法(线程安全)因此性能上比ArrayList要差
,LinkedList使用双向链表实现存储,按序号索引数据须要进行向前或向后遍历,可是插入数据时只须要记录本项的先后项便可,因此插入数度较快!
最后:List集合元素是有序可重复的集合,这与后面咱们讲到的set集合和map会有所不一样,另外List接口也提供iterator()方法,咱们前面贴出来过,咱们能够对集合元素进行迭代输出,属于很是使用高效的遍历操做,固然你也能够经过集合for循环或者数组遍历等操做,集合与数组之间支持互相转换,那么内容到此结束,谢谢你们!
期盼与你们一块儿在技术的道路不断成长,谢谢支持!